public IBatchStatistics process(INPUT target) throws Exception {
	try {
	    DefaultBatchStatistics stats = new DefaultBatchStatistics();
	    stats.setResultCaption("Read");
	    stats.setFrequency(1);

	    Iterator reader = getIterator(target);
	    ProcessorsChain<Target, IBatchStatistics, IProcessor> processor = getProcessorChain();
	    if (processor == null)
		throw new AmbitException("Processor not defined");
	    long started = System.currentTimeMillis();
	    while (reader.hasNext() && !cancelled) {
		if ((stats.getRecords(IBatchStatistics.RECORDS_STATS.RECORDS_READ) % stats.getFrequency()) == 0)
		    propertyChangeSupport.firePropertyChange(PROPERTY_BATCHSTATS, null, stats);
		Object object = null;
		long ms = System.currentTimeMillis();
		try {
		    object = reader.next();
		    stats.increment(IBatchStatistics.RECORDS_STATS.RECORDS_READ);
		    stats.incrementTimeElapsed(IBatchStatistics.RECORDS_STATS.RECORDS_READ, System.currentTimeMillis()
			    - ms);
		} catch (Exception x) {
		    stats.increment(IBatchStatistics.RECORDS_STATS.RECORDS_ERROR);
		    stats.incrementTimeElapsed(IBatchStatistics.RECORDS_STATS.RECORDS_ERROR, System.currentTimeMillis()
			    - ms);
		    continue;
		}
		ms = System.currentTimeMillis();
		try {
		    processor.process((Target) object);
		    stats.increment(IBatchStatistics.RECORDS_STATS.RECORDS_PROCESSED);
		    stats.incrementTimeElapsed(IBatchStatistics.RECORDS_STATS.RECORDS_PROCESSED,
			    System.currentTimeMillis() - ms);
		} catch (Exception x) {
		    stats.increment(IBatchStatistics.RECORDS_STATS.RECORDS_ERROR);
		    stats.incrementTimeElapsed(IBatchStatistics.RECORDS_STATS.RECORDS_ERROR, System.currentTimeMillis()
			    - ms);
		    continue;
		}
		long elapsed = System.currentTimeMillis() - started;
		if ((timeout > 0) && (elapsed > timeout)) {
		    stats.increment(IBatchStatistics.RECORDS_STATS.RECORDS_ERROR);
		    stats.incrementTimeElapsed(IBatchStatistics.RECORDS_STATS.RECORDS_ERROR, System.currentTimeMillis()
			    - ms);
		    break;

		}
	    }

	    propertyChangeSupport.firePropertyChange(PROPERTY_BATCHSTATS, null, stats);
	    closeIterator(reader);

	    return stats;
	} catch (Exception x) {
	    throw new AmbitException(x);
	}
    }