def migrate_rows
      # open an CSV output for rejects if the bad option is set
      if @bad_file then
        @rejects = open_rejects(@bad_file)
        logger.info("Unmigrated records will be written to #{File.expand_path(@bad_file)}.")
      end
      
      @rec_cnt = mgt_cnt = 0
      logger.info { "Migrating #{@input}..." }
      puts "Migrating #{@input}..." if @verbose
      @reader.each do |row|
        # the one-based current record number
        rec_no = @rec_cnt + 1
        # skip if the row precedes the from option
        if rec_no == @from and @rec_cnt > 0 then
          logger.info("Skipped the initial #{@rec_cnt} records.")
        elsif rec_no == @to then
          logger.info("Ending the migration after processing record #{@rec_cnt}.")
          return
        elsif rec_no < @from then
          @rec_cnt += 1
          next
        end
        begin
          # migrate the row
          logger.debug { "Migrating record #{rec_no}..." }
          tgt = migrate_row(row)
          # call the block on the migrated target
          if tgt then
            logger.debug { "The migrator built #{tgt} with the following content:\n#{tgt.dump}" }
            yield(tgt, row)
          end
        rescue Exception => e
          logger.error("Migration error on record #{rec_no} - #{e.message}:\n#{e.backtrace.pp_s}")
          # If there is a reject file, then don't propagate the error.
          raise unless @rejects
          # try to clear the migration state
          clear(tgt) rescue nil
          # clear the target
          tgt = nil
        end
        if tgt then
          # replace the log message below with the commented alternative to detect a memory leak
          logger.info { "Migrated record #{rec_no}." }
          #memory_usage = `ps -o rss= -p #{Process.pid}`.to_f / 1024 # in megabytes
          #logger.debug { "Migrated rec #{@rec_cnt}; memory usage: #{sprintf("%.1f", memory_usage)} MB." }
          mgt_cnt += 1
          if @verbose then print_progress(mgt_cnt) end
          # clear the migration state
          clear(tgt)
        elsif @rejects then
          # If there is a rejects file then warn, write the reject and continue.
          logger.warn("Migration not performed on record #{rec_no}.")
          @rejects << row
          @rejects.flush
          logger.debug("Invalid record #{rec_no} was written to the rejects file #{@bad_file}.")
        else
          raise MigrationError.new("Migration not performed on record #{rec_no}")
        end
        # Bump the record count.
        @rec_cnt += 1
      end
      logger.info("Migrated #{mgt_cnt} of #{@rec_cnt} records.")
      if @verbose then
        puts
        puts "Migrated #{mgt_cnt} of #{@rec_cnt} records."
      end
    end
def migrate_rows
      # open an CSV output for rejects if the bad option is set
      if @bad_file then
        @rejects = open_rejects(@bad_file)
        logger.info("Unmigrated records will be written to #{File.expand_path(@bad_file)}.")
      end
      
      @rec_cnt = mgt_cnt = 0
      logger.info { "Migrating #{@input}..." }
      puts "Migrating #{@input}..." if @verbose
      @reader.each do |row|
        # the one-based current record number
        rec_no = @rec_cnt + 1
        # skip if the row precedes the from option
        if rec_no == @from and @rec_cnt > 0 then
          logger.info("Skipped the initial #{@rec_cnt} records.")
        elsif rec_no == @to then
          logger.info("Ending the migration after processing record #{@rec_cnt}.")
          return
        elsif rec_no < @from then
          @rec_cnt += 1
          next
        end
        begin
          # migrate the row
          logger.debug { "Migrating record #{rec_no}..." }
          tgt = migrate_row(row)
          # call the block on the migrated target
          if tgt then
            logger.debug { "The migrator built #{tgt} with the following content:\n#{tgt.dump}" }
            yield(tgt, row)
          end
        rescue Exception => e
          logger.error("Migration error on record #{rec_no} - #{e.message}:\n#{e.backtrace.pp_s}")
          # If there is a reject file, then don't propagate the error.
          raise unless @rejects
          # try to clear the migration state
          clear(tgt) rescue nil
          # clear the target
          tgt = nil
        end
        if tgt then
          # replace the log message below with the commented alternative to detect a memory leak
          logger.info { "Migrated record #{rec_no}." }
          #memory_usage = `ps -o rss= -p #{Process.pid}`.to_f / 1024 # in megabytes
          #logger.debug { "Migrated rec #{@rec_cnt}; memory usage: #{sprintf("%.1f", memory_usage)} MB." }
          mgt_cnt += 1
          if @verbose then print_progress(mgt_cnt) end
          # clear the migration state
          clear(tgt)
        elsif @rejects then
          # If there is a rejects file then warn, write the reject and continue.
          logger.warn("Migration not performed on record #{rec_no}.")
          @rejects << row
          @rejects.flush
          logger.debug("Invalid record #{rec_no} was written to the rejects file #{@bad_file}.")
        else
          raise MigrationError.new("Migration not performed on record #{rec_no}")
        end
        # Bump the record count.
        @rec_cnt += 1
      end
      logger.info("Migrated #{mgt_cnt} of #{@rec_cnt} records.")
      if @verbose then
        puts
        puts "Migrated #{mgt_cnt} of #{@rec_cnt} records."
      end
    end
Migrates all rows in the input.

 @yield (see #migrate)
 @yieldparam (see #migrate)