function F = get_aux(infilename,policyproblem,instrumentname1,instrumentname2,extra_lag_flag,discount_factor_name)

% Authors: Joe LaBriola and Martin Bodenstein and Luca Guerrieri
% Takes a .mod file and removes lags in the exogenous variables
% before creating its Nash/Ramsey counterpart .mod file.

%% Checks to make sure inputs are acceptable
if nargin == 3
    if strcmp(policyproblem,'nash')
        error('You must specify two policy instruments to create the auxiliary file to be run through the Nash problem.')
    elseif ~strcmp(policyproblem,'one_agent_ramsey')
        error('Please provide two policy instruments.')
    end
end

if ~exist('extra_lag_flag','var')
   extra_lag_flag = 0;
end

if nargin >= 4
    if strcmp(policyproblem,'one_agent_ramsey')
        if instrumentname2 == '1' | instrumentname2 == '2'
            ramsey_agent_string = instrumentname2;
        else
            error('To run the simulation where one agent uses Ramsey policy, the fourth argument of this program must be the string ''1'' or ''2''');
        end

        if ramsey_agent_string == '1'
            other_agent_string = '2';
            new_infilename = [infilename,'_agent_1'];
        elseif ramsey_agent_string == '2'
            other_agent_string = '1';
            new_infilename = [infilename,'_agent_2'];
        end
    else
        new_infilename = infilename;
    end
end



%% Finds endogenous variables that have leads or lags.
lagvarmat = '';

endog_delim = 'Endogenous variables';
exog_delim = 'Exogenous variables';
delims = '()~+-*/=<>^; ';

util_string = 'Util';
welf_string = 'Welf';

% Set initial values of various variables
varflag = 0;
endogflag = 0;
exogflag = 0;
modelflag = 0;
iline = 1;
endovarmat = '';
exovarmat = '';

% Denotes if there's a 'shocks;' section. We've run into problems if lines
% inside this section begin with 'var ' , since this triggers the program
% into thinking the rest of the line should be deposited as endogenous
% variables.
shkblockflag = 0;

% Start processing blocks of lines from rawfile
rawfile = textread([infilename,'.mod'],'%s', ...
                    'delimiter','\n','whitespace','','bufsize',40000);

while iline <= length(rawfile)
  rawline = char(rawfile(iline));

  % Empty lines get skipped
  if isempty(deblank(rawline))

  % Skip comments after checking for the relevant delimiters
  elseif strncmp(strtok(rawline),'//',2)
    if ~isempty(strfind(rawline,endog_delim))
      endogflag = 1;
      exogflag = 0;
    elseif ~isempty(strfind(rawline,exog_delim))
      endogflag = 0;
      exogflag = 1;
    end

  elseif strncmpi(rawline,'shocks;',7)
    shkblockflag = 1;

  elseif shkblockflag && strncmpi(rawline,'end;',4)
      shkblockflag = 0;

% Start of model block
  elseif strncmpi(rawline,'model;',6)
      modelflag = 1;

% End of model block
  elseif modelflag && strncmpi(rawline,'end;',4)
    modelflag = 0;

% Individual model equation
  elseif modelflag
      for i = 1:size(endovarmat,1)
        if strfind(rawfile{iline},strcat(endovarmat(i,:),'(-1)'))
            lagvarmat = strvcat(lagvarmat, endovarmat(i,:));
        end
    end

% Variables
  elseif varflag | strncmpi(rawline,'var ',4) && ~shkblockflag
    tmpvarmat = '';
    if endogflag==0 & exogflag==0
      endogflag = 1;
    end
    if ~varflag
      rawline = rawline(5:length(rawline));
    end
    [varname,rest] = strtok(rawline,' ,;');
    if ~strcmp(varname, util_string) && ~strcmp(varname, welf_string)
            tmpvarmat = varname;
    end
    while ~isempty(rest)
      [varname,rest] = strtok(rest,' ,;');
      if ~strcmp(varname, util_string) && ~strcmp(varname, welf_string)
          tmpvarmat = strvcat(tmpvarmat,varname);
      end
    end
    if exogflag & strcmp(tmpvarmat,'') == 0
      exovarmat = strvcat(exovarmat,tmpvarmat);
    elseif strcmp(tmpvarmat,'') == 0
      endovarmat = strvcat(endovarmat,tmpvarmat);
    end
    if isempty(strfind(rawline,';'))
      varflag = 1;
    else
      varflag = 0;
    end
  end

% Increment line counter and go to top of loop
  iline = iline + 1;
end

lagvarmat = unique(lagvarmat,'rows');

% Minor edit to ensure that longer variable names that end with smaller
% variable names will be replaced before the smaller variable names.

for i = 1:size(lagvarmat,1)
    for j = i:size(lagvarmat,1)
        if strfind(lagvarmat(j,:),deblank(lagvarmat(i,:)))
            lagvarmat([i j],:) = lagvarmat([j i],:);
        end
    end
end
%% Modify .mod file to insert auxiliary variables

fin = fopen([infilename,'.mod'],'r');
fout = fopen([new_infilename,'_aux.mod'],'w');

var_block = 0;

%%%%%%%%%%%%%
add_to_param_block = 0;
new_vars_ss = [];
%%%%%%%%%%%%%


model_block = 0;
shock_block = 0;
deleteUtil1 = 0;
deleteUtil2 = 0;
new_vars = [];

for j = 1:size(lagvarmat,1)
    new_vars = strvcat(new_vars, strcat(lagvarmat(j,:),'lag'));
end

while ~feof(fin)
    s = fgets(fin);

% Adding policy variables to 'var;' block.
    if strncmp(s,'//',2) & ~strfind(s,'// auxiliary variables')
       fprintf(fout,'%s',s);

    elseif strncmp(s,'var ',4) & var_block == 0
       var_block = 1;
       rest_of_line = s(5:end);

       % Insert policy variables
       f2in = fopen(['template_for_',policyproblem,'policyvar.m'],'r');
       while ~feof(f2in)
          s = fgets(f2in);
          fprintf(fout,'%s',s);
       end
       fclose(f2in);

       if strcmp(policyproblem,'one_agent_ramsey')
           if deleteUtil1 == 0 & strfind(rest_of_line,'Util1')
               if strfind(rest_of_line,'Util1,')
                   rest_of_line = strrep(rest_of_line,'Util1,','');
               elseif strfind(rest_of_line,'Util1;')
                   rest_of_line = strrep(rest_of_line,'Util1','');
               end
               deleteUtil1 = 1;
           end

           if deleteUtil2 == 0 & strfind(rest_of_line,'Util2')
               if strfind(rest_of_line,'Util2,')
                   rest_of_line = strrep(rest_of_line,'Util2,','');
               elseif strfind(rest_of_line,'Util2;')
                   rest_of_line = strrep(rest_of_line,'Util2','');
               end
               deleteUtil2 = 1;
           end

           % If removing Util1/Util2 results in a comma immediately
           % preceding a semi-colon, remove the comma.
           if strfind(regexprep(rest_of_line,' ',''),',;')
               rest_of_line = deblank(regexprep(rest_of_line,' ',''));
               rest_of_line(length(rest_of_line) - 1) = [];
           end
       end

       % If there's a semi-colon at the end of the first line, insert the
       % auxiliary lagged variables here, and print out the original line
       % and the auxiliary variables. If not, print the original line.
       if strfind(rest_of_line,';')
           fprintf(fout,'%s \n',[rest_of_line(1:end-1),',']);
           for i = 1:size(new_vars,1)-1
               fprintf(fout,'%s \n',[deblank(new_vars(i,:)),',']);
           end

           if extra_lag_flag
               fprintf(fout,'%s \n',[deblank(new_vars(i+1,:)),',']);
           else
               fprintf(fout,'%s \n',[deblank(new_vars(i+1,:)),';'])
           end

           if extra_lag_flag
           for i = 1:size(new_vars,1)-1
               fprintf(fout,'%s \n',[deblank(new_vars(i,:)),'2,']);
           end
           fprintf(fout,'%s \n',[deblank(new_vars(size(new_vars,1),:)),'2;']);
           end

           var_block = 2;
       else
           fprintf(fout,'%s',rest_of_line);
       end

    elseif var_block == 1
        if strcmp(policyproblem,'one_agent_ramsey') && ((deleteUtil1 == 0 && ~isempty(strfind(s,'Util1'))) || (deleteUtil2 == 0 && ~isempty(strfind(s,'Util2'))))
            if deleteUtil1 == 0 & strfind(s,'Util1')
                if strfind(s,'Util1,')
                    s = strrep(s,'Util1,','');
                elseif strfind(s,'Util1;')
                    s = strrep(s,'Util1','');
                end
                deleteUtil1 = 1;
            end

            if deleteUtil2 == 0 & strfind(s,'Util2')
                if strfind(s,'Util2,')
                    s = strrep(s,'Util2,','');
                elseif strfind(s,'Util2;')
                    s = strrep(s,'Util2','');
                end
                deleteUtil2 = 1;
            end

            % If removing Util1/Util2 results in a comma immediately
            % preceding a semi-colon, remove the comma.
            if strfind(regexprep(s,' ',''),',;')
                s = regexprep(deblank(s),' ','');
                s(length(s) - 1) = [];
            end
        end

        % If there's a semi-colon at the end of the first line, insert the
        % auxiliary lagged variables here, and print out the original line
        % and the auxiliary variables. If not, print the original line.
        if strfind(s,';')
            deblanked_line = deblank(s);
            fprintf(fout,'%s \n',[deblanked_line(1:end-1),',']);
            for i = 1:size(new_vars,1)-1
                fprintf(fout,'%s \n',[deblank(new_vars(i,:)),',']);
            end

            if isempty(i)
                i = 0;
            end

            if extra_lag_flag
                fprintf(fout,'%s \n',[deblank(new_vars(i+1,:)),',']);
            else
                fprintf(fout,'%s \n',[deblank(new_vars(i+1,:)),';']);
            end

            if extra_lag_flag
            for i = 1:size(new_vars,1)-1
                fprintf(fout,'%s \n',[deblank(new_vars(i,:)),'2,']);
            end
            fprintf(fout,'%s \n',[deblank(new_vars(size(new_vars,1),:)),'2;']);
            end

            var_block = 2;
        else
           fprintf(fout,'%s',s);
        end


 %%%%%%%%%%%%%

% Adding policy parameters in 'parameters;' block.
    elseif strfind(s,'parameters ') & add_to_param_block == 0
        add_to_param_block = 1;
        fprintf(fout,'%s',s);
        for i = 1:size(new_vars_ss,1)
            fprintf(fout,'%s \n',[deblank(new_vars_ss(i,:)),',']);
        end

        f3in = fopen(['template_for_',policyproblem,'policyparam.m'],'r');
        while ~feof(f3in)
            s = fgets(f3in);
            fprintf(fout,'%s',s);
        end
        fclose(f3in);
  %%%%%%%%%%%%%








% Adding policy equations to 'model;' block.
    elseif strfind(s,'model;')

        model_block = 1;
        fprintf(fout,'%s',s);

        f4in = fopen(['template_for_',policyproblem,'policyblock.m'],'r');
        if ~strcmp(policyproblem,'one_agent_ramsey')
            while ~feof(f4in)
                s = fgets(f4in);
                s = strrep(s,'INSTRUMENT1',instrumentname1);
                s = strrep(s,'INSTRUMENT2',instrumentname2);
                fprintf(fout,'%s',s);
            end
        else
            while ~feof(f4in)
                s = fgets(f4in);
                s = strrep(s,'INSTRUMENT',instrumentname1);
                fprintf(fout,'%s',s);
            end
        end
        fclose(f4in);

        % Printing equations for auxiliary variables.

        fprintf(fout,'%s',' ');
        for i = 1:size(lagvarmat,1)
            deblanked_var = deblank(new_vars(i,:));
            fprintf(fout,'%s \n',strcat(deblanked_var,' =  ',deblanked_var(1:end-3),'(-1);'));
            if extra_lag_flag
            fprintf(fout,'%s \n',strcat(deblanked_var,'2 =  ',deblanked_var,'(-1);'));
            end
        end
        fprintf(fout,'%s',' ');


    elseif model_block == 1

    % Adding delimiters so the Ramsey/Nash program will know which equations
%     % are the policy equations.
%         if strncmp(regexprep(s,' ',''),[instrumentname1,'='],length(instrumentname1)+1)
%            fprintf(fout,'%s \n','// Policy rule, agent 1');
%         elseif strncmp(regexprep(s,' ',''),[instrumentname2,'='],length(instrumentname2)+1) && isempty(strmatch(policyproblem,'one_agent_ramsey'))
%            fprintf(fout,'%s \n','// Policy rule, agent 2');
%         end;

        % Editing policy equations in one-agent case.
        if strcmp(policyproblem,'one_agent_ramsey')
            if strncmp(regexprep(s,' ',''),['Util',ramsey_agent_string,'='],6)
                s = strrep(s,['Util',ramsey_agent_string],'Util');
            end
            if (strncmp(regexprep(s,' ',''),['Util',other_agent_string,'='],6)) | (strncmp(s,'//',2) & strfind(s,['Policy Rule, agent ',other_agent_string]))
                s = '';
            end
        end

        % Replacing lags with auxiliary variables.
        for i = 1:size(lagvarmat,1)
            deblanked_new_var = deblank(new_vars(i,:));
            backward_var = [deblank(lagvarmat(i,:)),'(-1)'];
            lag_location = strfind(s,backward_var);
            if lag_location & ~isempty(strfind(delims,s(lag_location - 1)))
                s = strrep(s,backward_var,deblanked_new_var);
            end
        end
        if strfind(s,'end;')
            model_block = 0;
        end
        fprintf(fout,'%s',s);

% Ignoring the 'shocks;' section.
    elseif strfind(s,'shocks;')
        shock_block = 1;
        %s = ['//', s];
        fprintf(fout,'%s',s);
    elseif shock_block == 1
        if strfind(s,'end;')
           shock_block = 0;
        end
        %s = ['//', s];
        fprintf(fout,'%s',s);

% If nothing above has been triggered, print from the original file.
    else
       fprintf(fout,'%s',s);
    end

end

%% Edit _ss_defs.m file.
cmd = [' copyfile ',infilename,'_ss_defs.m ', new_infilename,'_aux_ss_defs.m'];
eval(cmd);

f5in = fopen([new_infilename,'_aux_ss_defs.m'],'a');
f6in = fopen(['template_for_',policyproblem,'policysetss.m'],'r');

% Adding steady-states for policy variables.
if ~strcmp(policyproblem,'one_agent_ramsey')
    while ~feof(f6in)
        s = fgets(f6in);
        s = strrep(s,'INSTRUMENT1',instrumentname1);
        s = strrep(s,'INSTRUMENT2',instrumentname2);
        fprintf(f5in,'%s',s);
    end
    fclose(f6in);
else
    while ~feof(f6in)
        s = fgets(f6in);
        s = strrep(s,'INSTRUMENT',instrumentname1);
        s = strrep(s,'RAMSEY_CO_NUM',ramsey_agent_string);
        fprintf(f5in,'%s',s);
    end
    fclose(f6in);
end

% Adding steady-states for auxiliary variables.
for i = 1:size(lagvarmat,1)
    deblanked_var = deblank(new_vars(i,:));
    fprintf(f5in,'%s \n',strcat(deblanked_var,' =  ',deblanked_var(1:end-3),';'));
    fprintf(f5in,'%s \n',strcat(deblanked_var,'2 =  ',deblanked_var(1:end-3),';'));
end
fclose(f5in);

%% Edit _steadystate.m file.
f7in = fopen([infilename,'_steadystate.m'],'r');
f7out = fopen([new_infilename,'_aux_steadystate.m'],'w');

while ~feof(f7in)
    s = fgets(f7in);
    if strfind(s,infilename)
        new_line = regexprep(s,infilename,[new_infilename,'_aux']);
        fprintf(f7out,'%s \r',new_line);
    else
       fprintf(f7out,'%s',s);
    end
end
fclose(f7in);
fclose(f7out);


%% Copy _paramfile.m

%cmd = [' copyfile ', infilename,'_paramfile.m ', new_infilename,'_aux_paramfile.m'];
%eval(cmd);

%% Edit _paramfile.m file.
f8in = fopen([infilename,'_paramfile.m'],'r');
f8out = fopen([new_infilename,'_aux_paramfile.m'],'w');

while ~feof(f8in)
    s = fgets(f8in);
    fprintf(f8out,'%s',s);
end

% Setting auxiliary
fprintf(f8out,'\n',' ');
for i = 1:size(new_vars_ss,1)
    deblanked_ss = deblank(new_vars_ss(i,:));
    fprintf(f8out,'%s \n',[deblanked_ss,' = 0;']);
end

% Adding policy parameters to file.
f9in = fopen(['template_for_',policyproblem,'policyparamdef.m'],'r');
while ~feof(f9in)
    s = fgets(f9in);
    s = strrep(s,'BETANAME',discount_factor_name);
    fprintf(f8out,'%s',s);
end
fclose(f9in);
fclose(f8in);
fclose(f8out);
