diff --git a/compiler2/Setting.hh b/compiler2/Setting.hh
index 3eef9120a04a3604b7c173e7e497079c5dd05672..a105bbe173d4f7964fdbbe347ae4dc6f22e9d109 100644
--- a/compiler2/Setting.hh
+++ b/compiler2/Setting.hh
@@ -745,9 +745,10 @@ public:
   class Ref_simple : public Reference {
   public:
     enum reftype_t {
-      REF_BASIC, // basic reference (not class related to any class scope)
+      REF_BASIC, // basic reference (not related to a class scope or a dynamic template)
       REF_SUPER, // reference to the superclass
-      REF_THIS   // reference to the current class object
+      REF_THIS,  // reference to the current class object
+      REF_VALUE  // reference to the value being matched in a dynamic template
     };
   protected: // Derived classes need access
     /** Points to the referred assignment. Used for caching. */
diff --git a/compiler2/Value.cc b/compiler2/Value.cc
index 355c5a9c2a1acc48b1aa0b31cf97ac5e05b0d69f..54af76a944f7aa0fa052626c6679db7804490a04 100644
--- a/compiler2/Value.cc
+++ b/compiler2/Value.cc
@@ -4587,7 +4587,7 @@ namespace Common {
     case Assignment::A_PAR_TEMPL_IN:
     case Assignment::A_PAR_TEMPL_OUT:
     case Assignment::A_PAR_TEMPL_INOUT:
-      u.expr.t1=new Template(tmpref); // TEMPLATE_REFD constructor
+      u.expr.t1=new Template(Template::TEMPLATE_REFD, tmpref); // TEMPLATE_REFD constructor
       u.expr.t1->set_location(*tmpref);
       u.expr.t1->set_my_scope(get_my_scope());
       u.expr.t1->set_fullname(get_fullname()+".<operand>");
@@ -6704,7 +6704,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
       case Assignment::A_PAR_TEMPL_IN:
       case Assignment::A_PAR_TEMPL_OUT:
       case Assignment::A_PAR_TEMPL_INOUT: {
-        Template* t = new Template(ref->clone());
+        Template* t = new Template(Template::TEMPLATE_REFD, ref->clone());
         t->set_location(*ref);
         t->set_my_scope(get_my_scope());
         t->set_fullname(get_fullname()+".<operand>");
@@ -12043,7 +12043,7 @@ void Value::chk_expr_operand_execute_refd(Value *v1,
     case Assignment::A_PAR_TEMPL_IN:
     case Assignment::A_PAR_TEMPL_OUT:
     case Assignment::A_PAR_TEMPL_INOUT: {
-      Template* t = new Template(ref->clone());
+      Template* t = new Template(Template::TEMPLATE_REFD, ref->clone());
       t->set_location(*ref);
       t->set_my_scope(get_my_scope());
       t->set_fullname(get_fullname()+".<operand>");
diff --git a/compiler2/ttcn3/AST_ttcn3.cc b/compiler2/ttcn3/AST_ttcn3.cc
index 58529e1eddf3302af88e9374db9bf987d06d25d0..ba77515f579e3f05c0770ae3ef1fff1d605edab0 100644
--- a/compiler2/ttcn3/AST_ttcn3.cc
+++ b/compiler2/ttcn3/AST_ttcn3.cc
@@ -746,7 +746,7 @@ namespace Ttcn {
   : Ref_base(), reftype(p_reftype), parlist(NULL), params(NULL),
     gen_const_prefix(false), expr_cache(NULL)
   {
-    if (reftype != REF_THIS) {
+    if (reftype != REF_THIS && reftype != REF_VALUE) {
       FATAL_ERROR("Ttcn::Reference(): basic or 'super' reference with no ID");
     }
   }
diff --git a/compiler2/ttcn3/TtcnTemplate.cc b/compiler2/ttcn3/TtcnTemplate.cc
index 07c90a698eb60b7ae8c269a9a21e33a6b0fe6a13..e04463c3c96ef85e50f34443de49d81ca0c0af86 100644
--- a/compiler2/ttcn3/TtcnTemplate.cc
+++ b/compiler2/ttcn3/TtcnTemplate.cc
@@ -396,16 +396,26 @@ namespace Ttcn {
     }
   }
 
-  Template::Template(Reference *p_ref)
+  Template::Template(templatetype_t tt, Reference *p_ref)
     : GovernedSimple(S_TEMPLATE),
-      templatetype(TEMPLATE_REFD), my_governor(0), length_restriction(0),
+      templatetype(tt), my_governor(0), length_restriction(0),
       is_ifpresent(false), specific_value_checked(false),
       has_permutation(false), base_template(0)
   {
     if(!p_ref) FATAL_ERROR("Template::Template()");
-    u.ref.ref=p_ref;
-    u.ref.refd=0;
-    u.ref.refd_last=0;
+    switch (tt) {
+    case TEMPLATE_REFD:
+      u.ref.ref=p_ref;
+      u.ref.refd=0;
+      u.ref.refd_last=0;
+      break;
+    case DYNAMIC_MATCH:
+      delete p_ref;
+      // todo
+      break;
+    default:
+      FATAL_ERROR("Template::Template()");
+    }
   }
 
   Template::Template(templatetype_t tt, Templates *ts)
@@ -421,6 +431,7 @@ namespace Ttcn {
     case SUPERSET_MATCH:
     case SUBSET_MATCH:
     case PERMUTATION_MATCH:
+    case CONJUNCTION_MATCH:
       break;
     default:
       FATAL_ERROR("Template::Template()");
@@ -529,6 +540,33 @@ namespace Ttcn {
     u.dec_match.str_enc = v;
     u.dec_match.target = ti;
   }
+  
+  Template::Template(Template* prec, TemplateInstance* imp_t)
+    : GovernedSimple(S_TEMPLATE),
+      templatetype(IMPLICATION_MATCH), my_governor(0), length_restriction(0),
+      is_ifpresent(false), specific_value_checked(false),
+      has_permutation(false), flattened(true), base_template(0)
+  {
+    if (prec == NULL || imp_t == NULL) {
+      FATAL_ERROR("Template::Template()");
+    }
+    delete prec;
+    delete imp_t;
+    // todo
+  }
+  
+  Template::Template(StatementBlock* block)
+    : GovernedSimple(S_TEMPLATE),
+      templatetype(DYNAMIC_MATCH), my_governor(0), length_restriction(0),
+      is_ifpresent(false), specific_value_checked(false),
+      has_permutation(false), flattened(true), base_template(0)
+  {
+    if (block == NULL) {
+      FATAL_ERROR("Template::Template()");
+    }
+    delete block;
+    // todo
+  }
 
   Template::~Template()
   {
@@ -5813,7 +5851,7 @@ compile_time:
         // check, remove and delete after checked
         if (template_body->get_base_template())
           FATAL_ERROR("TemplateInstance::chk_restriction()");
-        template_body->set_base_template(new Template(derived_reference));
+        template_body->set_base_template(new Template(Template::TEMPLATE_REFD, derived_reference));
         needs_runtime_check = template_body->chk_restriction(
           definition_name, template_restriction, usage_loc);
         delete template_body->get_base_template();
diff --git a/compiler2/ttcn3/TtcnTemplate.hh b/compiler2/ttcn3/TtcnTemplate.hh
index 51e78ef81f5e0105003317710eded182acfdafdb..8226ec47d9fd5436089d3d76bd5ab73fef373227 100644
--- a/compiler2/ttcn3/TtcnTemplate.hh
+++ b/compiler2/ttcn3/TtcnTemplate.hh
@@ -69,7 +69,10 @@ namespace Ttcn {
       CSTR_PATTERN, /**< character string pattern */
       USTR_PATTERN, /**< universal charstring pattern */
       DECODE_MATCH, /**< decoded content match */
-      TEMPLATE_CONCAT /**< concatenation of two templates (runtime2 only) */
+      TEMPLATE_CONCAT, /**< concatenation of two templates (runtime2 only) */
+      CONJUNCTION_MATCH, /**< conjunction list match */
+      IMPLICATION_MATCH, /**< implication match */
+      DYNAMIC_MATCH /**< dynamic match */
     };
 
     /** Status codes for the verification of template body completeness. */
@@ -186,11 +189,11 @@ namespace Ttcn {
       * TEMPLATE_CONCAT (in which case it's recursive). */
     Template(Value *v);
 
-    /** Constructor for TEMPLATE_REFD */
-    Template(Reference *p_ref);
+    /** Constructor for TEMPLATE_REFD and DYNAMIC_MATCH */
+    Template(templatetype_t tt, Reference *p_ref);
 
     /** Constructor for TEMPLATE_LIST, VALUE_LIST, COMPLEMENTED_LIST,
-     * SUPERSET_MATCH, SUBSET_MATCH and PERMUTATION_MATCH */
+     * SUPERSET_MATCH, SUBSET_MATCH, PERMUTATION_MATCH and CONJUNCTION_MATCH  */
     Template(templatetype_t tt, Templates *ts);
 
     /** Constructor for ALL_FROM */
@@ -214,6 +217,13 @@ namespace Ttcn {
     /** Constructor for DECODE_MATCH */
     Template(Value* v, TemplateInstance* ti);
     
+    /** Constructor for IMPLICATION_MATCH */
+    Template(Template* prec, TemplateInstance* imp_t);
+    
+    /** Constructor for DYNAMIC_MATCH */
+    Template(StatementBlock* block);
+    
+    
     virtual ~Template();
 
     virtual Template* clone() const;
diff --git a/compiler2/ttcn3/compiler.l b/compiler2/ttcn3/compiler.l
index baaf0108ecf14c82025a6e804ecf56bbe65101e6..f66d30924bbb6258a5cd8ad928b701d2f5a83cbf 100644
--- a/compiler2/ttcn3/compiler.l
+++ b/compiler2/ttcn3/compiler.l
@@ -392,6 +392,7 @@ check		RETURN_DOT(CheckOpKeyword);
 clear		RETURN_DOT(ClearOpKeyword);
 complement	RETURN(ComplementKeyword);
 component	RETURN(ComponentKeyword);
+conjunct   RETURN(ConjunctKeyword);
 connect		RETURN(ConnectKeyword);
 const		RETURN(ConstKeyword);
 continue	RETURN(ContinueKeyword);
@@ -431,6 +432,7 @@ halt		RETURN_DOT(HaltKeyword);
 hexstring	RETURN(HexStringKeyword);
 if		RETURN(IfKeyword);
 ifpresent	RETURN(IfPresentKeyword);
+implies   RETURN(ImpliesKeyword);
 import		RETURN(ImportKeyword);
 in		RETURN(InParKeyword);
 inconc		RETURN(InconcKeyword);
@@ -637,6 +639,7 @@ object {
 "@final"         RETURN(FinalKeyword);
 "@abstract"      RETURN(AbstractKeyword);
 "@default"       RETURN(DefaultModifier);
+"@dynamic"       RETURN(DynamicModifier);
 
   /* special TITAN specific keywords */
 
diff --git a/compiler2/ttcn3/compiler.y b/compiler2/ttcn3/compiler.y
index 3b5f2dba79a6e2fa450f688de0c74b012bc42d9f..9ccd46f464ce46f89be55293de501f7b12a92ef1 100644
--- a/compiler2/ttcn3/compiler.y
+++ b/compiler2/ttcn3/compiler.y
@@ -613,6 +613,19 @@ static const string anyname("anytype");
     size_t nElements;
     StatementBlock** elements;
   } catch_block_list;
+  
+  struct {
+    Template* precondition;
+    TemplateInstance* implied_template;
+  } implication_match;
+  
+  struct {
+    bool is_ref;
+    union {
+      Ttcn::Reference* ref;
+      StatementBlock* sb;
+    };
+  } dynamic_match;
 }
 
 /* Tokens of TTCN-3 */
@@ -679,6 +692,7 @@ static const string anyname("anytype");
 %token ClearOpKeyword
 %token ComplementKeyword
 %token ComponentKeyword
+%token ConjunctKeyword
 %token ConnectKeyword
 %token ConstKeyword
 %token ContinueKeyword
@@ -720,6 +734,7 @@ static const string anyname("anytype");
 %token HexStringKeyword
 %token IfKeyword
 %token IfPresentKeyword
+%token ImpliesKeyword
 %token ImportKeyword
 %token InconcKeyword
 %token InfinityKeyword
@@ -831,6 +846,7 @@ static const string anyname("anytype");
 %token FinalKeyword
 %token AbstractKeyword
 %token DefaultModifier
+%token DynamicModifier
 
 /* TITAN specific keywords */
 %token TitanSpecificTryKeyword
@@ -1076,7 +1092,7 @@ static const string anyname("anytype");
 %type <templinsts>  optTemplateActualParList
   seqTemplateActualPar seqTemplateInstance
 %type <templs> ValueOrAttribList seqValueOrAttrib ValueList Complement
-  ArrayElementSpecList SubsetMatch SupersetMatch PermutationMatch
+  ArrayElementSpecList SubsetMatch SupersetMatch PermutationMatch ConjunctionMatch
 %type <ass> Assignment Step
 %type <reference> DerivedRefWithParList TemplateRefWithParList DecValueArg
   FunctionInstance AltstepInstance optBaseConstructorCall
@@ -1181,6 +1197,8 @@ AllOrTypeListWithTo TypeListWithFrom TypeListWithTo
 %type <reference_list> PortTypeList
 %type <string_vector> AttribSpecEncodings
 %type <catch_block_list> optCatchBlockList
+%type <implication_match> ImplicationMatch
+%type <dynamic_match> DynamicMatch
 
 /*********************************************************************
  * Destructors
@@ -1276,6 +1294,7 @@ CompoundExpression
 ConditionalConstruct
 ConfigurationOps
 ConfigurationStatements
+ConjunctionMatch
 ConnectStatement
 ContinueStatement
 ControlStatement
@@ -1957,6 +1976,22 @@ DecodedContentMatch
 }
 optDecodedModifier
 
+%destructor {
+  delete $$.precondition;
+  delete $$.implied_template;
+}
+ImplicationMatch
+
+%destructor {
+  if ($$.is_ref) {
+    delete $$.ref;
+  }
+  else {
+    delete $$.sb;
+  }
+}
+DynamicMatch
+
 
 /*********************************************************************
  * Operator precedences (lowest first)
@@ -1977,20 +2012,20 @@ optDecodedModifier
 %left '*' '/' ModKeyword RemKeyword
 %left UnarySign
 
-%expect 76
+%expect 92
 
 %start GrammarRoot
 
 /*
-XXX Source of conflicts (75 S/R):
+XXX Source of conflicts (92 S/R):
 
-1.) 12 conflicts in one state
+1.) 13 conflicts in one state
 The Expression after 'return' keyword is optional in ReturnStatement.
-For 12 tokens the parser cannot decide whether the token is a part of
+For 13 tokens the parser cannot decide whether the token is a part of
 the return expression (shift) or it is the beginning of the next statement
 (reduce).
 
-2.) 13 distinct states, each with one conflict caused by token '['
+2.) 14 distinct states, each with one conflict caused by token '['
 The local definitions in altsteps can be followed immediately by the guard
 expression. When the parser sees the '[' token it cannot decide whether it
 belongs to the local definition as array dimension or array subreference
@@ -2009,6 +2044,7 @@ The situations are the following:
 - var t v := this.field <here> [
 - var t v := this.function(...) <here> [
 - var t v := super.function(...) <here> [
+- var t v := value<subrefs> <here> [
 
 3.) 1 conflict
 The sequence identifier.objid can be either the beginning of a module name
@@ -2025,9 +2061,9 @@ non-standard language extension.
 
 6.) 1 Conflict due to pattern concatenation
 
-7.) 30 conflicts in one state
+7.) 31 conflicts in one state
 In the DecodedContentMatch rule a SingleExpression encased in round brackets is
-followed by an in-line template. For 30 tokens (after the ')' ) the parser cannot
+followed by an in-line template. For 31 tokens (after the ')' ) the parser cannot
 decide whether the token is the beginning of the in-line template (shift) or
 the brackets are only part of the SingleExpression itself and the conflicting
 token is the next segment in the expression (reduce).
@@ -2070,6 +2106,38 @@ ex.: 'a(1)' is treated as the objid component with name 'a' and number '1' (shif
 instead of the component with the number returned by function 'a' with '1' as
 its parameter (reduce).
 
+14.) 13 conflicts in 9 states
+These are caused by the implication matching template rule (i.e. ImplicationMatch),
+specifically because the rule ends in a TemplateInstance, and the rule itself can be
+embedded inside another TemplateInstance.
+ - The 'length' and 'ifpresent' keywords after an implication match template can
+be interpreted as attributes of the implied template (i.e. the 2nd operand)
+in the implication match template (shift), or as attributes of the entire implication
+match template (reduce). This causes 2 conflicts (one for each keyword) in 4 states
+(the first 4 options of the TemplateBody rule).
+ - Similarly, if there is an 'ifpresent' after a length restriction at the end of an
+implication match template, then it can be considered as an attribute of the implied
+template (shift), or as an attribute of the entire implication match template (reduce). 
+ - Implication matching templates can be chained (e.g. 't1 implies t2 implies t3').
+The first 'implies' keyword in this case can be considered as part of the precondition
+of the resulting template (whose precondition is 't1 implies t2' and whose implied
+template is 't3'). This is the shift case.
+It can also be considered as the resulting template's 'implies' keyword (in which case
+the precondition would be 't1' and the implied tempalte would be 't2 implies t3').
+This is the reduce case.
+Semantically both cases mean the same thing.
+ - Similarly, if a template instance in the middle of an implication match chain has a
+type indicator, a derived reference, or both a type indicator and a derived reference,
+then the following 'implies' keyword can be considered as part of the result template's
+precondition (shift). In this case the type and/or derived reference only affect the
+template operand before the mentioned 'implies' keyword.
+Or it can be the 'implies' keyword of the resulting template (reduce), in which case
+the type and/or derived reference would affect the entire implication match template that
+starts before the mentioned 'implies' keyword and ends after the final 'implies' keyword.
+(For example in 't1 implies MyType: t2 implies t3'
+'MyType:' could indicate the type of 't2' (shift) or the type of 't2 implies t3' (reduce).
+
+
 Note that the parser implemented by bison always chooses to shift instead of
 reduce in case of conflicts.
 */
@@ -4206,13 +4274,33 @@ MatchingSymbol: // 116 is a Template*
     $$ = new Template(Template::SUPERSET_MATCH, $1);
     $$->set_location(infile, @$);
   }
+| ConjunctionMatch
+  {
+    $$ = new Template(Template::CONJUNCTION_MATCH, $1);
+    $$->set_location(infile, @$);
+  }
+| ImplicationMatch
+  {
+    $$ = new Template($1.precondition, $1.implied_template);
+    $$->set_location(infile, @$);
+  }
+| DynamicMatch
+  {
+    if ($1.is_ref) {
+      $$ = new Template(Template::DYNAMIC_MATCH, $1.ref);
+    }
+    else {
+      $$ = new Template($1.sb);
+    }
+    $$->set_location(infile, @$);
+  }
 ;
 
 optExtraMatchingAttributes: // [117]
   /* empty */
   {
-    $$.is_ifpresent = false;
     $$.len_restr = NULL;
+    $$.is_ifpresent = false;
   }
 | LengthMatch
   {
@@ -4340,6 +4428,33 @@ DecodedContentMatch:
   }
 ;
 
+ConjunctionMatch:
+  ConjunctKeyword ValueList { $$ = $2; }
+;
+
+ImplicationMatch:
+  TemplateBody ImpliesKeyword TemplateInstance
+  {
+    $$.precondition = $1;
+    $$.implied_template = $3;
+  }
+/*| TemplateBody ImpliesKeyword '(' TemplateInstance ')' --- handled by TemplateListElem */
+;
+
+DynamicMatch:
+  DynamicModifier StatementBlock
+  {
+    $$.is_ref = false;
+    $$.sb = $2;
+  }
+| DynamicModifier FunctionRef
+  {
+    $$.is_ref = true;
+    $$.ref = new Ttcn::Reference($2.modid, $2.id);
+    $$.ref->set_location(infile, @2);
+  }
+;
+
 AnyValue: // 140
   '?'
 ;
@@ -8888,6 +9003,14 @@ Reference: // 490 ValueReference
     Free($7.elements);
     $$.ref->set_location(infile, @$);
   }
+| ValueKeyword optExtendedFieldReference
+  {
+    $$.is_ref = true;
+    $$.ref = new Ttcn::Reference(Ref_simple::REF_VALUE);
+    for (size_t i = 0; i < $2.nElements; i++) $$.ref->add($2.elements[i]);
+    Free($2.elements);
+    $$.ref->set_location(infile, @$);
+  }
 ;
 
 /* A.1.6.5 Parameterization */
diff --git a/core/Basetype.hh b/core/Basetype.hh
index add2b7acc505aa428e8044a81da5ceb5772d5c45..c09c66bcf98eeb29f16b4783ebbf7a8d5011b1a5 100644
--- a/core/Basetype.hh
+++ b/core/Basetype.hh
@@ -1237,6 +1237,20 @@ public:
   virtual ~Dec_Match_Interface() {}
 };
 
+template <typename T>
+class Dynamic_Match_Interface {
+public:
+  virtual boolean match(const T&) = 0;
+  virtual ~Dynamic_Match_Interface() {}
+};
+
+template <typename T>
+struct dynmatch_struct {
+  unsigned int ref_count;
+  Dynamic_Match_Interface<T>* ptr;
+};
+    
+
 /** Interface/base class for value redirects in RT2
   *
   * For every value redirect the compiler generates a new class that inherits
diff --git a/core/Integer.cc b/core/Integer.cc
index 18064b080894313b762279f45f881a01347ea7ad..1ac0dc593a9fd46dc9c432f5d2ce7f9aa376f094 100644
--- a/core/Integer.cc
+++ b/core/Integer.cc
@@ -2077,6 +2077,7 @@ void INTEGER_template::clean_up()
       break;
     case VALUE_LIST:
     case COMPLEMENTED_LIST:
+    case CONJUNCTION_MATCH:
       delete [] value_list.list_value;
       break;
     case VALUE_RANGE:
@@ -2085,6 +2086,17 @@ void INTEGER_template::clean_up()
       if (value_range.max_is_present && unlikely(!value_range.max_value.native_flag))
         BN_free(value_range.max_value.val.openssl);
       break;
+    case IMPLICATION_MATCH:
+      delete implication_.precondition;
+      delete implication_.implied_template;
+      break;
+    case DYNAMIC_MATCH:
+      dyn_match->ref_count--;
+      if (dyn_match->ref_count == 0) {
+        delete dyn_match->ptr;
+        delete dyn_match;
+      }
+      break;
     default:
       break;
   }
@@ -2106,6 +2118,7 @@ void INTEGER_template::copy_template(const INTEGER_template& other_value)
     break;
   case VALUE_LIST:
   case COMPLEMENTED_LIST:
+  case CONJUNCTION_MATCH:
     value_list.n_values = other_value.value_list.n_values;
     value_list.list_value = new INTEGER_template[value_list.n_values];
     for (unsigned int i = 0; i < value_list.n_values; i++)
@@ -2136,6 +2149,14 @@ void INTEGER_template::copy_template(const INTEGER_template& other_value)
           BN_dup(other_value.value_range.max_value.val.openssl);
     }
     break;
+  case IMPLICATION_MATCH:
+    implication_.precondition = new INTEGER_template(*other_value.implication_.precondition);
+    implication_.implied_template = new INTEGER_template(*other_value.implication_.implied_template);
+    break;
+  case DYNAMIC_MATCH:
+    dyn_match = other_value.dyn_match;
+    dyn_match->ref_count++;
+    break;
   default:
     TTCN_error("Copying an uninitialized/unsupported integer template.");
   }
@@ -2196,6 +2217,21 @@ INTEGER_template::INTEGER_template(const INTEGER_template& other_value)
   copy_template(other_value);
 }
 
+INTEGER_template::INTEGER_template(INTEGER_template* p_precondition, INTEGER_template* p_implied_template)
+: Base_Template(IMPLICATION_MATCH)
+{
+  implication_.precondition = p_precondition;
+  implication_.implied_template = p_implied_template;
+}
+
+INTEGER_template::INTEGER_template(Dynamic_Match_Interface<INTEGER>* p_dyn_match)
+: Base_Template(DYNAMIC_MATCH)
+{
+  dyn_match = new dynmatch_struct<INTEGER>;
+  dyn_match->ptr = p_dyn_match;
+  dyn_match->ref_count = 1;
+}
+
 INTEGER_template::~INTEGER_template()
 {
   clean_up();
@@ -2310,6 +2346,17 @@ boolean INTEGER_template::match(int other_value, boolean /* legacy */) const
       }
     }
     return lower_boundary && upper_boundary; }
+  case CONJUNCTION_MATCH:
+    for (unsigned int i = 0; i < value_list.n_values; i++) {
+      if (!value_list.list_value[i].match(other_value)) {
+        return FALSE;
+      }
+    }
+    return TRUE;
+  case IMPLICATION_MATCH:
+    return !implication_.precondition->match(other_value) || implication_.implied_template->match(other_value);
+  case DYNAMIC_MATCH:
+    return dyn_match->ptr->match(other_value);
   default:
     TTCN_error("Matching with an uninitialized/unsupported integer "
       "template.");
@@ -2365,6 +2412,17 @@ boolean INTEGER_template::match(const INTEGER& other_value,
       }
       }
       return lower_boundary && upper_boundary; }
+    case CONJUNCTION_MATCH:
+      for (unsigned int i = 0; i < value_list.n_values; i++) {
+        if (!value_list.list_value[i].match(other_value)) {
+          return FALSE;
+        }
+      }
+      return TRUE;
+    case IMPLICATION_MATCH:
+      return !implication_.precondition->match(other_value) || implication_.implied_template->match(other_value);
+    case DYNAMIC_MATCH:
+      return dyn_match->ptr->match(other_value);
     default:
       TTCN_error("Matching with an uninitialized/unsupported integer "
         "template.");
@@ -2388,6 +2446,7 @@ void INTEGER_template::set_type(template_sel template_type,
   switch (template_type) {
   case VALUE_LIST:
   case COMPLEMENTED_LIST:
+  case CONJUNCTION_MATCH:
     set_selection(template_type);
     value_list.n_values = list_length;
     value_list.list_value = new INTEGER_template[list_length];
@@ -2407,7 +2466,8 @@ void INTEGER_template::set_type(template_sel template_type,
 INTEGER_template& INTEGER_template::list_item(unsigned int list_index)
 {
   if (template_selection != VALUE_LIST &&
-      template_selection != COMPLEMENTED_LIST)
+      template_selection != COMPLEMENTED_LIST &&
+      template_selection != CONJUNCTION_MATCH)
     TTCN_error("Accessing a list element of a non-list integer template.");
   if (list_index >= value_list.n_values)
     TTCN_error("Index overflow in an integer value list template.");
@@ -2524,6 +2584,11 @@ void INTEGER_template::log() const
   case COMPLEMENTED_LIST:
     TTCN_Logger::log_event_str("complement");
     // no break
+  case CONJUNCTION_MATCH:
+    if (template_selection == CONJUNCTION_MATCH) {
+      TTCN_Logger::log_event_str("conjunct");
+    }
+    // no break
   case VALUE_LIST:
     TTCN_Logger::log_char('(');
     for (unsigned int i = 0; i < value_list.n_values; i++) {
@@ -2559,6 +2624,14 @@ void INTEGER_template::log() const
     }
     TTCN_Logger::log_char(')');
     break;
+  case IMPLICATION_MATCH:
+    implication_.precondition->log();
+    TTCN_Logger::log_event_str(" implies ");
+    implication_.implied_template->log();
+    break;
+  case DYNAMIC_MATCH:
+    TTCN_Logger::log_event_str("@dynamic template");
+    break;
   default:
     log_generic();
     break;
@@ -2840,6 +2913,8 @@ boolean INTEGER_template::match_omit(boolean legacy /* = FALSE */) const
   case OMIT_VALUE:
   case ANY_OR_OMIT:
     return TRUE;
+  case IMPLICATION_MATCH:
+    return !implication_.precondition->match_omit() || implication_.implied_template->match_omit();
   case VALUE_LIST:
   case COMPLEMENTED_LIST:
     if (legacy) {
diff --git a/core/Integer.hh b/core/Integer.hh
index 42705bfa672aa48d1324341e6b6bbad03ec96003..25d0f9aa07c53936c11d98fe2424a1c39aab71db 100644
--- a/core/Integer.hh
+++ b/core/Integer.hh
@@ -264,6 +264,11 @@ private:
         } val;
       } min_value, max_value;
     } value_range;
+    struct {
+      INTEGER_template* precondition;
+      INTEGER_template* implied_template;
+    } implication_;
+    dynmatch_struct<INTEGER>* dyn_match;
   };
 
   void copy_template(const INTEGER_template& other_value);
@@ -275,6 +280,8 @@ public:
   INTEGER_template(int other_value);
   INTEGER_template(const INTEGER& other_value);
   INTEGER_template(const OPTIONAL<INTEGER>& other_value);
+  INTEGER_template(INTEGER_template* p_precondition, INTEGER_template* p_implied_template);
+  INTEGER_template(Dynamic_Match_Interface<INTEGER>* p_dyn_match);
   ~INTEGER_template();
   void clean_up();
 
diff --git a/core/Template.hh b/core/Template.hh
index 26f1ee76643ee9a8624f4647dd0c3e9108a642d6..dc35f42cd66681414900a6278ad2db999a3f7c45 100644
--- a/core/Template.hh
+++ b/core/Template.hh
@@ -54,7 +54,10 @@ enum template_sel {
   STRING_PATTERN = 7,
   SUPERSET_MATCH = 8,
   SUBSET_MATCH = 9,
-  DECODE_MATCH = 10
+  DECODE_MATCH = 10,
+  CONJUNCTION_MATCH = 11,
+  IMPLICATION_MATCH = 12,
+  DYNAMIC_MATCH = 13
 };
 
 enum template_res {