diff --git a/DataTree.cc b/DataTree.cc
index e4220bcdd5ced2c46fd386f5cb9da43531e54f54..68a96e40ea2f4051eb49332f7ecb5f3e04048cf5 100644
--- a/DataTree.cc
+++ b/DataTree.cc
@@ -269,6 +269,12 @@ DataTree::AddAdl(expr_t iArg1, const string &name, int lag)
   return AddUnaryOp(oAdl, iArg1, 0, 0, 0, string(name), lag);
 }
 
+expr_t
+DataTree::AddAdl(expr_t iArg1, const string &name, const vector<int> &lags)
+{
+  return AddUnaryOp(oAdl, iArg1, 0, 0, 0, string(name), -1, lags);
+}
+
 expr_t
 DataTree::AddExp(expr_t iArg1)
 {
diff --git a/DataTree.hh b/DataTree.hh
index 72f8086d45baa546afcd59e60422b56f72bcab9d..33049c783c96051befed8c2371ba7d50d08047f8 100644
--- a/DataTree.hh
+++ b/DataTree.hh
@@ -64,7 +64,7 @@ protected:
   variable_node_map_t variable_node_map;
   //! Pair( Pair(arg1, UnaryOpCode), Pair( Expectation Info Set, Pair(param1_symb_id, param2_symb_id)) ))
 
-  typedef map<pair<pair<expr_t, UnaryOpcode>, pair<pair<int, pair<int, int> >, pair<string, int> > >, UnaryOpNode *> unary_op_node_map_t;
+  typedef map<pair<pair<expr_t, UnaryOpcode>, pair<pair<int, pair<int, int> >, pair<string, pair<int, vector<int> > > > >, UnaryOpNode *> unary_op_node_map_t;
   unary_op_node_map_t unary_op_node_map;
   //! Pair( Pair( Pair(arg1, arg2), order of Power Derivative), opCode)
   typedef map<pair<pair<pair<expr_t, expr_t>, int>, BinaryOpcode>, BinaryOpNode *> binary_op_node_map_t;
@@ -104,7 +104,7 @@ private:
   int node_counter;
 
   inline expr_t AddPossiblyNegativeConstant(double val);
-  inline expr_t AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set = 0, int param1_symb_id = 0, int param2_symb_id = 0, const string &adl_param_name = "", int adl_param_lag = -1);
+  inline expr_t AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set = 0, int param1_symb_id = 0, int param2_symb_id = 0, const string &adl_param_name = "", int adl_param_lag = -1, const vector<int> &adl_lags = vector<int>());
   inline expr_t AddBinaryOp(expr_t arg1, BinaryOpcode op_code, expr_t arg2, int powerDerivOrder = 0);
   inline expr_t AddTrinaryOp(expr_t arg1, TrinaryOpcode op_code, expr_t arg2, expr_t arg3);
 
@@ -167,6 +167,7 @@ public:
   expr_t AddDiff(expr_t iArg1);
   //! Adds "adl(arg1, arg2)" to model tree
   expr_t AddAdl(expr_t iArg1, const string &name, int lag);
+  expr_t AddAdl(expr_t iArg1, const string &name, const vector<int> &lags);
   //! Adds "exp(arg)" to model tree
   expr_t AddExp(expr_t iArg1);
   //! Adds "log(arg)" to model tree
@@ -317,10 +318,10 @@ DataTree::AddPossiblyNegativeConstant(double v)
 }
 
 inline expr_t
-DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int param1_symb_id, int param2_symb_id, const string &adl_param_name, int adl_param_lag)
+DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int param1_symb_id, int param2_symb_id, const string &adl_param_name, int adl_param_lag, const vector<int> &adl_lags)
 {
   // If the node already exists in tree, share it
-  unary_op_node_map_t::iterator it = unary_op_node_map.find(make_pair(make_pair(arg, op_code), make_pair(make_pair(arg_exp_info_set, make_pair(param1_symb_id, param2_symb_id)), make_pair(adl_param_name, adl_param_lag))));
+  unary_op_node_map_t::iterator it = unary_op_node_map.find(make_pair(make_pair(arg, op_code), make_pair(make_pair(arg_exp_info_set, make_pair(param1_symb_id, param2_symb_id)), make_pair(adl_param_name, make_pair(adl_param_lag, adl_lags)))));
   if (it != unary_op_node_map.end())
     return it->second;
 
@@ -339,7 +340,7 @@ DataTree::AddUnaryOp(UnaryOpcode op_code, expr_t arg, int arg_exp_info_set, int
         {
         }
     }
-  return new UnaryOpNode(*this, op_code, arg, arg_exp_info_set, param1_symb_id, param2_symb_id, adl_param_name, adl_param_lag);
+  return new UnaryOpNode(*this, op_code, arg, arg_exp_info_set, param1_symb_id, param2_symb_id, adl_param_name, adl_param_lag, adl_lags);
 }
 
 inline expr_t
diff --git a/DynareBison.yy b/DynareBison.yy
index d95f77d3cf275b5e30fda0cc08cbacf9613c92f8..446f88c8b9b74f6f021875821e2e34d94dd68495 100644
--- a/DynareBison.yy
+++ b/DynareBison.yy
@@ -890,6 +890,8 @@ hand_side : '(' hand_side ')'
             { $$ = driver.add_adl($3, $5, new string("1")); }
           | ADL '(' hand_side COMMA QUOTED_STRING COMMA INT_NUMBER ')'
             { $$ = driver.add_adl($3, $5, $7); }
+          | ADL '(' hand_side COMMA QUOTED_STRING COMMA vec_int ')'
+            { $$ = driver.add_adl($3, $5, $7); }
           | LOG '(' hand_side ')'
             { $$ = driver.add_log($3); }
           | LN '(' hand_side ')'
diff --git a/ExprNode.cc b/ExprNode.cc
index 7bc69fb3c3b6d90f50a8bda00c081e0effa675ae..80063559fcef7ce3a70214a94e29828d773ac71e 100644
--- a/ExprNode.cc
+++ b/ExprNode.cc
@@ -1601,7 +1601,7 @@ VariableNode::getEndosAndMaxLags(map<string, int> &model_endos_and_lags) const
       model_endos_and_lags[varname] = lag;
 }
 
-UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg, const string &adl_param_name_arg, int adl_param_lag_arg) :
+UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg, const string &adl_param_name_arg, int adl_param_lag_arg, vector<int> adl_lags_arg) :
   ExprNode(datatree_arg),
   arg(arg_arg),
   expectation_information_set(expectation_information_set_arg),
@@ -1609,13 +1609,14 @@ UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const
   param2_symb_id(param2_symb_id_arg),
   op_code(op_code_arg),
   adl_param_name(adl_param_name_arg),
-  adl_param_lag(adl_param_lag_arg)
+  adl_param_lag(adl_param_lag_arg),
+  adl_lags(adl_lags_arg)
 {
   // Add myself to the unary op map
   datatree.unary_op_node_map[make_pair(make_pair(arg, op_code),
                                        make_pair(make_pair(expectation_information_set,
                                                            make_pair(param1_symb_id, param2_symb_id)),
-                                                 make_pair(adl_param_name, adl_param_lag)))] = this;
+                                                 make_pair(adl_param_name, make_pair(adl_param_lag, adl_lags))))] = this;
 }
 
 void
@@ -2716,21 +2717,43 @@ UnaryOpNode::substituteAdlAndDiff() const
     }
 
   expr_t arg1subst = arg->substituteAdlAndDiff();
-  int i = 1;
+  expr_t retval;
   ostringstream inttostr;
-  inttostr << i;
-  expr_t retval = datatree.AddTimes(datatree.AddVariable(datatree.symbol_table.getID(adl_param_name + "_lag_" + inttostr.str()), 0),
-                                    arg1subst->decreaseLeadsLags(i));
-  i++;
-  for (; i <= adl_param_lag; i++)
-    {
-      inttostr.clear();
-      inttostr.str("");
+  if (adl_param_lag >= 0)
+    {
+      int i = 1;
       inttostr << i;
-      retval = datatree.AddPlus(retval,
-                                datatree.AddTimes(datatree.AddVariable(datatree.symbol_table.getID(adl_param_name + "_lag_" + inttostr.str()), 0),
-                                                  arg1subst->decreaseLeadsLags(i)));
+      retval = datatree.AddTimes(datatree.AddVariable(datatree.symbol_table.getID(adl_param_name + "_lag_" + inttostr.str()), 0),
+                                 arg1subst->decreaseLeadsLags(i));
+      i++;
+      for (; i <= adl_param_lag; i++)
+        {
+          inttostr.clear();
+          inttostr.str("");
+          inttostr << i;
+          retval = datatree.AddPlus(retval,
+                                    datatree.AddTimes(datatree.AddVariable(datatree.symbol_table.getID(adl_param_name + "_lag_" + inttostr.str()), 0),
+                                                      arg1subst->decreaseLeadsLags(i)));
+        }
     }
+  else
+    for (vector<int>::const_iterator it = adl_lags.begin(); it != adl_lags.end(); it++)
+      if (it == adl_lags.begin())
+        {
+          inttostr << *it;
+          retval = datatree.AddTimes(datatree.AddVariable(datatree.symbol_table.getID(adl_param_name + "_lag_" + inttostr.str()), 0),
+                                     arg1subst->decreaseLeadsLags(*it));
+        }
+      else
+        {
+          inttostr.clear();
+          inttostr.str("");
+          inttostr << *it;
+          retval = datatree.AddPlus(retval,
+                                    datatree.AddTimes(datatree.AddVariable(datatree.symbol_table.getID(adl_param_name + "_lag_"
+                                                                                                       + inttostr.str()), 0),
+                                                      arg1subst->decreaseLeadsLags(*it)));
+        }
   return retval;
 }
 
diff --git a/ExprNode.hh b/ExprNode.hh
index aafd3d23f6ca13ff0109cea0f8c69fe88392e4b8..2d963e274a74427d19f71c4025916e9263c6aeba 100644
--- a/ExprNode.hh
+++ b/ExprNode.hh
@@ -635,6 +635,7 @@ private:
   const UnaryOpcode op_code;
   const string adl_param_name;
   const int adl_param_lag;
+  const vector<int> adl_lags;
   virtual expr_t computeDerivative(int deriv_id);
   virtual int cost(int cost, bool is_matlab) const;
   virtual int cost(const temporary_terms_t &temporary_terms, bool is_matlab) const;
@@ -642,7 +643,7 @@ private:
   //! Returns the derivative of this node if darg is the derivative of the argument
   expr_t composeDerivatives(expr_t darg, int deriv_id);
 public:
-  UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg, const string &adl_param_name_arg, int adl_param_lag_arg);
+  UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const expr_t arg_arg, int expectation_information_set_arg, int param1_symb_id_arg, int param2_symb_id_arg, const string &adl_param_name_arg, int adl_param_lag_arg, vector<int> adl_lags_arg);
   virtual void prepareForDerivation();
   virtual void computeTemporaryTerms(map<expr_t, pair<int, NodeTreeReference> > &reference_count,
                                      map<NodeTreeReference, temporary_terms_t> &temp_terms_map,
diff --git a/ParsingDriver.cc b/ParsingDriver.cc
index d8a1b1ea9b94b5e1643fb6531492612bc28a860d..d8b317f0a1a47e8684cf10fc767081f467da2b4b 100644
--- a/ParsingDriver.cc
+++ b/ParsingDriver.cc
@@ -2612,6 +2612,24 @@ ParsingDriver::add_adl(expr_t arg1, string *name, string *lag)
   return id;
 }
 
+expr_t
+ParsingDriver::add_adl(expr_t arg1, string *name, vector<int> *lags)
+{
+  expr_t id = data_tree->AddAdl(arg1, *name, *lags);
+
+  // Declare parameters here so that parameters can be initialized after the model block
+  for (vector<int>::const_iterator it = lags->begin(); it != lags->end(); it++)
+    {
+      ostringstream inttostr;
+      inttostr << *it;
+      declare_parameter(new string(*name + "_lag_" + inttostr.str()));
+    }
+
+  delete name;
+  delete lags;
+  return id;
+}
+
 expr_t
 ParsingDriver::add_log(expr_t arg1)
 {
diff --git a/ParsingDriver.hh b/ParsingDriver.hh
index be533089ca2ce1f666d8479890fe8bacf07b59ca..9e6cebbe3b57dbd6c34960c4759a1445e55141ed 100644
--- a/ParsingDriver.hh
+++ b/ParsingDriver.hh
@@ -672,6 +672,7 @@ public:
   expr_t add_diff(expr_t arg1);
   //! Writes token "adl(arg1, lag)" to model tree
   expr_t add_adl(expr_t arg1, string *name, string *lag);
+  expr_t add_adl(expr_t arg1, string *name, vector<int> *lags);
   //! Writes token "exp(arg1)" to model tree
   expr_t add_exp(expr_t arg1);
   //! Writes token "log(arg1)" to model tree