diff --git a/matlab/dyn_first_order_solver.m b/matlab/dyn_first_order_solver.m
index 8309d1fa3b5549fd25720714d761aab41f0ae364..c4d6c4693598b534c9c5f05a772ec9e47979f8b8 100644
--- a/matlab/dyn_first_order_solver.m
+++ b/matlab/dyn_first_order_solver.m
@@ -64,8 +64,11 @@ function [dr,info] = dyn_first_order_solver(jacobia,DynareModel,dr,DynareOptions
 % You should have received a copy of the GNU General Public License
 % along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
 
-persistent reorder_jacobian_columns innovations_idx index_s index_m index_c index_p row_indx index_0m index_0p k1 k2 j3 j4 state_var
-persistent ndynamic nstatic nfwrd npred nboth nd nyf n
+persistent reorder_jacobian_columns innovations_idx index_s index_m index_c
+persistent index_p row_indx index_0m index_0p k1 k2 state_var
+persistent ndynamic nstatic nfwrd npred nboth nd nyf n_current index_d 
+persistent index_e index_d1 index_d2 index_e1 index_e2 row_indx_de_1 
+persistent row_indx_de_2 cols_b
 
 
 if ~nargin
@@ -76,8 +79,11 @@ if ~nargin
     return
 end
 
-if isempty(reorder_jacobian_columns)
+exo_nbr = DynareModel.exo_nbr;
 
+if isempty(reorder_jacobian_columns)
+    
+    maximum_lag = DynareModel.maximum_endo_lag;
     kstate   = dr.kstate;
     nfwrd    = dr.nfwrd;
     nboth    = dr.nboth;
@@ -85,7 +91,7 @@ if isempty(reorder_jacobian_columns)
     nstatic  = dr.nstatic;
     ndynamic = npred+nfwrd+nboth;
     nyf      = nfwrd + nboth;
-    n        = ndynamic+nstatic;
+    n        = DynareModel.endo_nbr;
 
     k1 = 1:(npred+nboth);
     k2 = 1:(nfwrd+nboth);
@@ -95,44 +101,60 @@ if isempty(reorder_jacobian_columns)
     lead_lag_incidence = DynareModel.lead_lag_incidence;
     nz = nnz(lead_lag_incidence);
 
-    %lead variables actually present in the model
-    j4 = nstatic+npred+1:nstatic+npred+nboth+nfwrd;   % Index on the forward and both variables
-    j3 = nonzeros(lead_lag_incidence(2,j4)) - nstatic - 2 * npred - nboth;  % Index on the non-zeros forward and both variables
-    j4 = find(lead_lag_incidence(2,j4));
-
-    no_lead_id = find(lead_lag_incidence(3,:)==0);
-    no_lag_id = find(lead_lag_incidence(1,:)==0);
-
-    static_id = intersect(no_lead_id,no_lag_id);
-    lag_id = setdiff(no_lead_id,static_id);
-    lead_id = setdiff(no_lag_id,static_id);
-    both_id = intersect(setdiff(1:n,no_lead_id),setdiff(1:n,no_lag_id));
-
-    lead_idx = lead_lag_incidence(3,lead_id);
-    lag_idx = lead_lag_incidence(1,lag_id);
-    both_lagged_idx = lead_lag_incidence(1,both_id);
-    both_leaded_idx = lead_lag_incidence(3,both_id);
-    innovations_idx = (size(jacobia,2)-DynareModel.exo_nbr+1):size(jacobia,2);
-    state_var  = [lag_idx, both_lagged_idx];
-
-    indexi_0 = 0;
-    if DynareModel.maximum_endo_lag > 0 && (npred > 0  || nboth > 0)
-        indexi_0 = min(lead_lag_incidence(2,:));
+    lead_id = find(lead_lag_incidence(maximum_lag+2,:));
+    lead_idx = lead_lag_incidence(maximum_lag+2,lead_id);
+    if maximum_lag
+        lag_id = find(lead_lag_incidence(1,:));
+        lag_idx = lead_lag_incidence(1,lag_id);
+        static_id = find((lead_lag_incidence(1,:) == 0) & ...
+                         (lead_lag_incidence(3,:) == 0));
+    else
+        lag_id = [];
+        lag_idx = [];
+        static_id = find(lead_lag_incidence(2,:)==0);
     end
 
-    index_c  = lead_lag_incidence(2,:);             % Index of all endogenous variables present at time=t
-    index_s  = lead_lag_incidence(2,1:nstatic);     % Index of all static endogenous variables present at time=t
-    index_0m = (nstatic+1:nstatic+npred)+indexi_0-1;
-    index_0p = (nstatic+npred+1:n)+indexi_0-1;
-    index_m  = 1:(npred+nboth);
-    index_p  = lead_lag_incidence(3,find(lead_lag_incidence(3,:)));
-    row_indx = nstatic+1:n;
+    both_id = intersect(lead_id,lag_id);
+    if maximum_lag
+        no_both_lag_id = setdiff(lag_id,both_id);
+    else
+        no_both_lag_id = [];
+    end
+    innovations_idx = nz+(1:exo_nbr);
+    state_var  = [lag_id, both_id];
 
-    reorder_jacobian_columns = [lag_idx, both_lagged_idx, npred+nboth+[static_id lag_id both_id lead_id], both_leaded_idx, lead_idx, innovations_idx ];
+    index_c  = nonzeros(lead_lag_incidence(maximum_lag+1,:));             % Index of all endogenous variables present at time=t
+    n_current = length(index_c);
 
-end
+    index_s  = npred+nboth+(1:nstatic);     % Index of all static
+                                            % endogenous variables
+                                            % present at time=t
+    indexi_0 = npred+nboth;
 
-info = 0;
+    npred0 = nnz(lead_lag_incidence(maximum_lag+1,no_both_lag_id));
+    index_0m = indexi_0+nstatic+(1:npred0);
+    nfwrd0 = nnz(lead_lag_incidence(2,lead_id));
+    index_0p = indexi_0+nstatic+npred0+(1:nfwrd0);
+    index_m  = 1:(npred+nboth);
+    index_p  = npred+nboth+n_current+(1:(nfwrd+nboth));
+    row_indx_de_1 = 1:ndynamic;
+    row_indx_de_2 = ndynamic+1:nboth;
+    row_indx = nstatic+row_indx_de_1;
+    index_d = [index_0m index_p];
+    llx = lead_lag_incidence(:,order_var);
+    index_d1 = [find(llx(maximum_lag+1,nstatic+(1:npred))), npred+nboth+(1:nyf) ];
+    index_d2 = npred+1:nboth;
+
+    index_e = [index_m index_0p];
+    index_e1 = [1:(npred+nboth), npred+nboth+find(llx(maximum_lag+1,nstatic+npred+(1: ...
+                                                      nyf)))];
+    index_e2 = npred+nboth+nfwrd+1:nboth;
+    
+    [junk,cols_b] = find(lead_lag_incidence(maximum_lag+1, order_var));
+
+    reorder_jacobian_columns = [nonzeros(lead_lag_incidence(:,order_var)'); ...
+                        nz+(1:exo_nbr)'];
+end
 
 dr.ghx = [];
 dr.ghu = [];
@@ -149,32 +171,49 @@ else
 end
 
 A = aa(:,index_m);  % Jacobain matrix for lagged endogeneous variables
-B = aa(:,index_c);  % Jacobian matrix for contemporaneous endogeneous variables
+B(:,cols_b) = aa(:,index_c);  % Jacobian matrix for contemporaneous endogeneous variables
 C = aa(:,index_p);  % Jacobain matrix for led endogeneous variables
 
+info = 0;
+info1 = 1;
 if task ~= 1 && (DynareOptions.dr_cycle_reduction || DynareOptions.dr_logarithmic_reduction)
+    if n_current < DynareModel.endo_nbr
+        if DynareOptions.dr_cycle_reduction
+            error(['The cycle reduction algorithme can''t be used when the ' ...
+               'coefficient matrix for current variables is singular'])
+        elseif DynareOptions.dr_logarithmic_reduction
+            error(['The logarithmic reduction algorithme can''t be used when the ' ...
+                   'coefficient matrix for current variables is singular'])
+        end
+    end        
     A1 = [aa(row_indx,index_m ) zeros(ndynamic,nfwrd)];
     B1 = [aa(row_indx,index_0m) aa(row_indx,index_0p) ];
     C1 = [zeros(ndynamic,npred) aa(row_indx,index_p)];
     if DynareOptions.dr_cycle_reduction == 1
-        [ghx, info] = cycle_reduction(A1, B1, C1, DynareOptions.dr_cycle_reduction_tol);
+        [ghx, info1] = cycle_reduction(A1, B1, C1, DynareOptions.dr_cycle_reduction_tol);
     else
-        [ghx, info] = logarithmic_reduction(C1, B1, A1, DynareOptions.dr_logarithmic_reduction_tol, DynareOptions.dr_logarithmic_reduction_maxiter);
+        [ghx, info1] = logarithmic_reduction(C1, B1, A1, DynareOptions.dr_logarithmic_reduction_tol, DynareOptions.dr_logarithmic_reduction_maxiter);
     end
     ghx = ghx(:,index_m);
     hx = ghx(1:npred+nboth,:);
     gx = ghx(1+npred:end,:);
 end
 
-if (task ~= 1 && ((DynareOptions.dr_cycle_reduction == 1 && info ==1) || DynareOptions.dr_cycle_reduction == 0)) || task == 1
-    D = [[aa(row_indx,index_0m) zeros(ndynamic,nboth) aa(row_indx,index_p)] ; [zeros(nboth, npred) eye(nboth) zeros(nboth, nboth + nfwrd)]];
+if info1 == 1
+    D = zeros(ndynamic+nboth);
+    E = zeros(ndynamic+nboth);
+    D(row_indx_de_1,index_d1) = aa(row_indx,index_d);
+    D(row_indx_de_2,index_d2) = eye(nboth);
+    E(row_indx_de_1,index_e1) = -aa(row_indx,index_e);
+    E(row_indx_de_2,index_e2) = eye(nboth);
+    
     E = [-aa(row_indx,[index_m index_0p])  ; [zeros(nboth,nboth+npred) eye(nboth,nboth+nfwrd) ] ];
 
-    [err, ss, tt, w, sdim, dr.eigval, info1] = mjdgges(E,D,DynareOptions.qz_criterium);
+    [err, ss, tt, w, sdim, dr.eigval, info2] = mjdgges(E,D,DynareOptions.qz_criterium);
     mexErrCheck('mjdgges', err);
 
-    if info1
-        if info1 == -30
+    if info2
+        if info2 == -30
             % one eigenvalue is close to 0/0
             info(1) = 7;
         else
@@ -211,65 +250,64 @@ if (task ~= 1 && ((DynareOptions.dr_cycle_reduction == 1 && info ==1) || DynareO
     end
 
     %First order approximation
-    if task ~= 1
-        indx_stable_root = 1: (nd - nyf);     %=> index of stable roots
-        indx_explosive_root = npred + nboth + 1:nd;  %=> index of explosive roots
-                                                     % derivatives with respect to dynamic state variables
-                                                     % forward variables
-        Z = w';
-        Z11t = Z(indx_stable_root,    indx_stable_root)';
-        Z21  = Z(indx_explosive_root, indx_stable_root);
-        Z22  = Z(indx_explosive_root, indx_explosive_root);
-        if ~isfloat(Z21) && (condest(Z21) > 1e9)
-            info(1) = 5;
-            info(2) = condest(Z21);
-            return;
-        else
-            gx = - Z22 \ Z21;
-        end
-        % predetermined variables
-        hx =  Z11t * inv(tt(indx_stable_root, indx_stable_root)) * ss(indx_stable_root, indx_stable_root) * inv(Z11t);
-        ghx = [hx(k1,:); gx(k2(nboth+1:end),:)];
-    end;
-end
+    indx_stable_root = 1: (nd - nyf);     %=> index of stable roots
+    indx_explosive_root = npred + nboth + 1:nd;  %=> index of explosive roots
+                                                 % derivatives with respect to dynamic state variables
+                                                 % forward variables
+    Z = w';
+    Z11t = Z(indx_stable_root,    indx_stable_root)';
+    Z21  = Z(indx_explosive_root, indx_stable_root);
+    Z22  = Z(indx_explosive_root, indx_explosive_root);
+    if ~isfloat(Z21) && (condest(Z21) > 1e9)
+        info(1) = 5;
+        info(2) = condest(Z21);
+        return;
+    else
+        gx = - Z22 \ Z21;
+    end
+    % predetermined variables
+    hx =  Z11t * inv(tt(indx_stable_root, indx_stable_root)) * ss(indx_stable_root, indx_stable_root) * inv(Z11t);
+    ghx = [hx(k1,:); gx(k2(nboth+1:end),:)];
 
-if  task~= 1
+end
 
-    if nstatic > 0
-        B_static = B(:,1:nstatic);  % submatrix containing the derivatives w.r. to static variables
-    else
-        B_static = [];
-    end;
-    %static variables, backward variable, mixed variables and forward variables
-    B_pred = B(:,nstatic+1:nstatic+npred+nboth);
-    B_fyd = B(:,nstatic+npred+nboth+1:end);
+dr.gx = gx;
 
-    % static variables
-    if nstatic > 0
-        temp = - C(1:nstatic,j3)*gx(j4,:)*hx;
-        b = aa(:,index_c);
-        b10 = b(1:nstatic, 1:nstatic);
-        b11 = b(1:nstatic, nstatic+1:n);
-        temp(:,index_m) = temp(:,index_m)-A(1:nstatic,:);
-        temp = b10\(temp-b11*ghx);
-        ghx = [temp; ghx];
-        temp = [];
-    end
+if nstatic > 0
+    B_static = B(:,1:nstatic);  % submatrix containing the derivatives w.r. to static variables
+else
+    B_static = [];
+end;
+%static variables, backward variable, mixed variables and forward variables
+B_pred = B(:,nstatic+1:nstatic+npred+nboth);
+B_fyd = B(:,nstatic+npred+nboth+1:end);
 
-    A_ = real([B_static C(:,j3)*gx+B_pred B_fyd]); % The state_variable of the block are located at [B_pred B_both]
+% static variables
+if nstatic > 0
+    temp = - C(1:nstatic,:)*gx*hx;
+    b(:,cols_b) = aa(:,index_c);
+    b10 = b(1:nstatic, 1:nstatic);
+    b11 = b(1:nstatic, nstatic+1:end);
+    temp(:,index_m) = temp(:,index_m)-A(1:nstatic,:);
+    temp = b10\(temp-b11*ghx);
+    ghx = [temp; ghx];
+    temp = [];
+end
 
-    if DynareModel.exo_nbr
-        if nstatic > 0
-            fu = Q' * jacobia(:,innovations_idx);
-        else
-            fu = jacobia(:,innovations_idx);
-        end;
+A_ = real([B_static C*gx+B_pred B_fyd]); % The state_variable of the block are located at [B_pred B_both]
 
-        ghu = - A_ \ fu;
+if exo_nbr
+    if nstatic > 0
+        fu = Q' * jacobia(:,innovations_idx);
     else
-        ghu = [];
+        fu = jacobia(:,innovations_idx);
     end;
-end
+
+    ghu = - A_ \ fu;
+else
+    ghu = [];
+end;
+
 
 
 dr.ghx = ghx;