context: //#undef GENERICS
  #define GENERICS
  #if NET_2_0
  
  
  using System;
  using System.Collections;
  using System.Diagnostics;
  
  #if GENERICS
  using System.Collections.Generic;
  #endif
  
  
  namespace FileHelpers
  {
  
  
  	/// <summary>Engine used to create diff files based on the <see cref="IComparableRecord"/> interface.</summary>
  #if NET_2_0
      [DebuggerDisplay("FileDiffEngine for type: {RecordType.Name}. ErrorMode: {ErrorManager.ErrorMode.ToString()}. Encoding: {Encoding.EncodingName}")]
  #endif
  #if ! GENERICS
  	public sealed class FileDiffEngine: EngineBase
  #else
      /// <typeparam name="T">The record type.</typeparam>
      public sealed class FileDiffEngine<T>: EngineBase
  		where T: IComparableRecord
  #endif
      {
  		/// <summary>
  		/// Creates a new <see cref="FileDiffEngine"/>
  		/// </summary>
  		/// <param name="recordType">The record type class that implements the <see cref="IComparableRecord"/> interface.</param>
  #if ! GENERICS
  		public FileDiffEngine(Type recordType):base(recordType)
  		{
  			if (typeof(IComparableRecord).IsAssignableFrom(recordType) == false)
  				throw new BadUsageException("The record class '" + "' need to implement the interface IComparableRecord.");
  		}
  #else
  		public FileDiffEngine():base(typeof(T))
  		{
  		}
  #endif
  
  
  		/// <summary>Returns the records in newFile that not are in the sourceFile</summary>
  		/// <param name="sourceFile">The file with the old records.</param>
  		/// <param name="newFile">The file with the new records.</param>
  		/// <returns>The records in newFile that not are in the sourceFile</returns>
  #if ! GENERICS
  		public object[] OnlyNewRecords(string sourceFile, string newFile)
  		{
  			FileHelperEngine engine = CreateEngineAndClearErrors();
  			
  			IComparableRecord[] olds = (IComparableRecord[]) engine.ReadFile(sourceFile);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
  			IComparableRecord[] currents = (IComparableRecord[]) engine.ReadFile(newFile);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
              
  			ArrayList news = new ArrayList();
  			ApplyDiffOnlyIn1(currents, olds, news);
  
  			return (object[]) news.ToArray(mRecordInfo.mRecordType);
  		} 
  #else
  		public T[] OnlyNewRecords(string sourceFile, string newFile)
  		{
  			FileHelperEngine<T> engine = CreateEngineAndClearErrors();
  			
  			T[] olds = engine.ReadFile(sourceFile);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
  			T[] currents = engine.ReadFile(newFile);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
              
  			List<T> news = new List<T>();
  			ApplyDiffOnlyIn1(currents, olds, news);
  
  			return news.ToArray();
  		} 
  #endif
  
  		
  		/// <summary>Returns the records in newFile that not are in the sourceFile</summary>
  		/// <param name="sourceFile">The file with the old records.</param>
  		/// <param name="newFile">The file with the new records.</param>
  		/// <returns>The records in newFile that not are in the sourceFile</returns>
  #if ! GENERICS
  		public object[] OnlyMissingRecords(string sourceFile, string newFile)
  		{
  			FileHelperEngine engine = CreateEngineAndClearErrors();
  
  			IComparableRecord[] olds = (IComparableRecord[]) engine.ReadFile(sourceFile);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
  
  			IComparableRecord[] currents = (IComparableRecord[]) engine.ReadFile(newFile);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
              
  			ArrayList news = new ArrayList();
  
  			ApplyDiffOnlyIn1(olds, currents, news);
  
  			return (object[]) news.ToArray(mRecordInfo.mRecordType);
  		}
  #else
  		public T[] OnlyMissingRecords(string sourceFile, string newFile)
  		{
  			FileHelperEngine<T> engine = CreateEngineAndClearErrors();
  
  			T[] olds = engine.ReadFile(sourceFile);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
  
  			T[] currents = engine.ReadFile(newFile);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
              
  			List<T> news = new List<T>();
  
  			ApplyDiffOnlyIn1(olds, currents, news);
  
  			return news.ToArray();
  		}
  #endif
  		
  #if ! GENERICS
  		private FileHelperEngine CreateEngineAndClearErrors()
  		{
  			FileHelperEngine engine = new FileHelperEngine(mRecordInfo);
  #else
  		private FileHelperEngine<T> CreateEngineAndClearErrors()
  		{
  			FileHelperEngine<T> engine = new FileHelperEngine<T>();
  #endif
  			engine.Encoding = this.Encoding;
  
  			ErrorManager.ClearErrors();
  			engine.ErrorManager.ErrorMode = this.ErrorManager.ErrorMode;
  			
  			return engine;
  		}
  
  
  		/// <summary>
  		/// Returns the duplicated records in both files.
  		/// </summary>
  		/// <param name="file1">A file with record.</param>
  		/// <param name="file2">A file with record.</param>
  		/// <returns>The records that appear in both files.</returns>
  #if ! GENERICS
  		public object[] OnlyDuplicatedRecords(string file1, string file2)
  		{
  			FileHelperEngine engine = CreateEngineAndClearErrors();
  			
  			IComparableRecord[] olds = (IComparableRecord[]) engine.ReadFile(file1);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
  			IComparableRecord[] currents = (IComparableRecord[]) engine.ReadFile(file2);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
              
  			ArrayList news = new ArrayList();
  
  			ApplyDiffInBoth(currents, olds, news);
  
  			return (object[]) news.ToArray(mRecordInfo.mRecordType);
  		}
  #else
  		public T[] OnlyDuplicatedRecords(string file1, string file2)
  		{
  			FileHelperEngine<T> engine = CreateEngineAndClearErrors();
  			
  			T[] olds = engine.ReadFile(file1);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
  			T[] currents = engine.ReadFile(file2);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
              
  			List<T> news = new List<T>();
  
  			ApplyDiffInBoth(currents, olds, news);
  
  			return news.ToArray();
  		}
  #endif
  
  		#region "  ApplyDiff  "
  
  #if ! GENERICS		
  		private static void ApplyDiffInBoth(IComparableRecord[] col1, IComparableRecord[] col2, ArrayList arr)
  		{
  			ApplyDiff(col1, col2, arr, true);
  		}
  
  		private static void ApplyDiffOnlyIn1(IComparableRecord[] col1, IComparableRecord[] col2, ArrayList arr)
  		{
  			ApplyDiff(col1, col2, arr, false);
  		}
  
  		private static void ApplyDiff(IComparableRecord[] col1, IComparableRecord[] col2, ArrayList arr, bool addIfIn1)
  		{
  			for(int i = 0; i < col1.Length; i++)
  			{
  				bool isNew = false; 
  				
  				//OPT: aca podemos hacer algo asi que para cada nuevo 
  				//     que encuentra no empieze en j = i sino en j = i - nuevos =)
  				//     Otra idea de guille es agrear un window y usar el Max de las dos
  
  				IComparableRecord current = col1[i];
  #else
  		private static void ApplyDiffInBoth(T[] col1, T[] col2, List<T> arr)
  		{
  			ApplyDiff(col1, col2, arr, true);
  		}
  
  		private static void ApplyDiffOnlyIn1(T[] col1, T[] col2, List<T> arr)
  		{
  			ApplyDiff(col1, col2, arr, false);
  		}
  
  		private static void ApplyDiff(T[] col1, T[] col2, List<T> arr, bool addIfIn1)
  		{
  			for(int i = 0; i < col1.Length; i++)
  			{
  				bool isNew = false; 
  				
  				//OPT: aca podemos hacer algo asi que para cada nuevo 
  				//     que encuentra no empieze en j = i sino en j = i - nuevos =)
  				//     Otra idea de guille es agrear un window y usar el Max de las dos
  
  				T current = col1[i];
  #endif
  		
  				for(int j = i; j < col2.Length; j++)
  				{
  					if (current.IsEqualRecord(col2[j]))
  					{
  						isNew = true;
  						break;
  					}
  				}
  
  				
  				if (isNew == false)
  				{
  					for(int j = 0; j < Math.Min(i, col2.Length); j++)
  					{
  						if (current.IsEqualRecord(col2[j]))
  						{
  							isNew = true;
  							break;
  						}
  					}
  				}
  
  				if (isNew == addIfIn1) arr.Add(current); 
  
  			}
  		}
  
  		#endregion
  
  		/// <summary>
  		/// Returns the NON duplicated records in both files.
  		/// </summary>
  		/// <param name="file1">A file with record.</param>
  		/// <param name="file2">A file with record.</param>
  		/// <returns>The records that NOT appear in both files.</returns>
  #if ! GENERICS
  		public object[] OnlyNoDuplicatedRecords(string file1, string file2)
  		{
  			FileHelperEngine engine = CreateEngineAndClearErrors();
  			
  			IComparableRecord[] olds = (IComparableRecord[]) engine.ReadFile(file1);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
  			IComparableRecord[] currents = (IComparableRecord[]) engine.ReadFile(file2);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
              
  			ArrayList news = new ArrayList();
  
  			ApplyDiffOnlyIn1(currents, olds, news);
  
  			ApplyDiffOnlyIn1(olds, currents, news);
  
  			return (object[]) news.ToArray(mRecordInfo.mRecordType);
      
  		} 
  #else
  		public T[] OnlyNoDuplicatedRecords(string file1, string file2)
  		{
  			FileHelperEngine<T> engine = CreateEngineAndClearErrors();
  			
  			T[] olds = engine.ReadFile(file1);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
  			T[] currents = engine.ReadFile(file2);
  			this.ErrorManager.AddErrors(engine.ErrorManager);
              
  
gt: 			List<T> news = new List<T>();