#
open(F,$ARGV[0]) || die "Cannot open $ARGV[0]: $!";
while(<F>) {
   if ( $_ =~ /^\s*DO\s* jj/i) {
      # Start processing loop if line contains DO jj (case and whitespace independent)
      #
      # 1. Store the current line
      #
      $jline = $_;
      #
      # 2. Read the next line and check if it contains DO ji
      #
      my $iline = <F> || die "DO jj line at end of file $ARGV[0]?"; 
      if ( $iline =~ /^\s*do\s*ji/i) {
         #
         # 3. Initialise a count to track any nested do loops
         #
         my $docount = 0;
         #
         # 4. Store the loop limits from the two lines stored and remove spaces and new-lines
         #
         ($jargs = $jline) =~ s/(^.*?)=([^\!\n]*)(\!*.*)/\2/;
         ($iargs = $iline) =~ s/(^.*?)=([^\!\n]*)(\!*.*)/\2/;
         chomp($iargs);
         chomp($jargs);
         $iargs =~ s/^\s+//; $iargs =~ s/\s+$//;
         $jargs =~ s/^\s+//; $jargs =~ s/\s+$//;
         @ilims = split(/,/,$iargs);
         @jlims = split(/,/,$jargs);
         #
         # 5. Convert i-limits into Gurvan's indexing
         # i.e. lower limit: [2,fs_2] --> 0 ; 1--> 1
         # i.e. upper limit: *m* --> 0 else --> 1
         #
         if( @ilims[0] =~ /2/ ) {
           @ilims[0] = 0;
         } elsif ( @ilims[0] == 1 ) {
           @ilims[0] = 1;
         }
         if( @ilims[1] =~ /m/ ) {
           @ilims[1] = 0;
         } else {
           @ilims[1] = 1;
         }
         $iargs = join(', ',@ilims[0], @ilims[1]);
         #
         # 6. Convert j-limits into Gurvan's indexing
         # i.e. lower limit: [2,fs_2] --> 0 ; 1--> 1
         # i.e. upper limit: *m* --> 0 else --> 1
         #
         if( @jlims[0] =~ /2/ ) {
           @jlims[0] = 0;
         } elsif ( @jlims[0] == 1 ) {
           @jlims[0] = 1;
         }
         if( @jlims[1] =~ /m/ ) {
           @jlims[1] = 0;
         } else {
           @jlims[1] = 1;
         }
         $jargs = join(', ',@jlims[0], @jlims[1]);
         #
         # 7. Store the leading indentation for the outer loop
         #
         ($jspac = $jline) =~ s/(^[\s]*)([^\s]*).*/\1/;
         chomp($jspac);
         #
         # 8. Construct a DO_2D line to replace the original statements
         #
         print $jspac,join('',"DO_2D( ",$iargs,', ',$jargs,' )'),"\n"; 
         #
         # 9. Now process the loop contents until the matching pair of END DO statements
         #
         while ( $docount >= 0 || ! ( $iline =~ /^\s*end\s*do/i ) ) {
            $iline = <F> || die "reached end of file $ARGV[0] within do loop?" ;
            #
            # 10. Increment a counter if another DO statement is found
            #
            if ( $iline =~ /^\s*do\s*/i )  { $docount++ };
            #
            # 11. Decrement a counter if a END DO statement is found
            #
            if ( $iline =~ /^\s*end\s*do/i || $iline =~ /^.*;\s*end\s*do/i )  { $docount-- };
            #
            # 12. A negative counter means the matching END DO for the ji loop has been reached
            #
            if ( $docount < 0 ) {
               #
               # 13. Check the next line is the expected 2nd END DO. 
               #     Output END_2D statement if it is
               #
               $jline = <F> || die "reached end of  $ARGV[0] looking for end do?" ;
               if ( ! ($jline =~ /^\s*end\s*do/i) )  { 
                  die "END DOs are not consecutive in $ARGV[0]";
               } else {
                  print $jspac,"END_2D\n";
               }
            
            } else {
               #
               # 14. This is a line inside the loop. Remove three leading spaces (if any) and output.
               #
               $iline =~ s/^\s\s\s//; 
               print $iline;
            }
         }
      } else {
         #
         # 15. Consecutive DO statements were not found. Do not process these loops.
         #
         print $jline;
         print $iline;
      }
   } else {
      #
      # 16. Code outside of a DO construct. Leave unchanged.
      #
      print $_;
   }
}
