/// <summary>
		/// Returns a RollFileEntry that represents the next state of the current file,
		/// based on the current state.  When the current state would roll, the next
		/// entry is the current file wrapped to 0 bytes.  Otherwise, the next state
		/// is the post-condition passed in as the currentNext parameter
		/// </summary>
		/// <param name="rollingStats"></param>
		/// <param name="currentNext"></param>
		/// <returns></returns>
		private static RollFileEntry MoveNextEntry(RollingStats rollingStats, RollFileEntry currentNext)
		{
			rollingStats.MessagesThisFile = rollingStats.MessagesThisFile + 1;
			if (rollingStats.MessagesThisFile >= rollingStats.MessagesPerFile)
			{
				rollingStats.MessagesThisFile = 0;
				rollingStats.NumberOfFileRolls = rollingStats.NumberOfFileRolls + 1;

				return new RollFileEntry(GetCurrentFile(), 0);
			}
			else
			{
				return currentNext;
			}
		}
		/// <summary>
		/// Generates the pre and post condition arrays from an array of backup files and the
		/// current file / next file.
		/// </summary>
		/// <param name="sBackupFiles"></param>
		/// <param name="preCondition"></param>
		/// <param name="current"></param>
		/// <param name="currentNext"></param>
		/// <param name="rollingStats"></param>
		/// <returns></returns>
		private static RollConditions BuildTableEntry(string sBackupFiles, RollConditions preCondition, RollFileEntry current, RollFileEntry currentNext, RollingStats rollingStats)
		{
			RollFileEntry[] backupsPost = MakeBackupFileEntriesForPostCondition(sBackupFiles, rollingStats);
			RollFileEntry[] post = AddFinalElement(backupsPost, currentNext);
			if (null == preCondition)
			{
				return new RollConditions(AddFinalElement(null, current), post);
			}
			return new RollConditions(preCondition.GetPostLogFileEntries(), post);
		}
		///// <summary>
		///// Builds a collection of file entries based on the file names
		///// specified in a groups string and the max file size from the
		///// stats object
		///// </summary>
		///// <param name="sBackupGroups"></param>
		///// <param name="stats"></param>
		///// <returns></returns>
		//private RollFileEntry[] MakeBackupFileEntriesForPreCondition( string sBackupGroups, RollingStats stats )
		//{
		//    if (0 == stats.NumberOfFileRolls )
		//    {
		//        return null;	// first round has no previous backups
		//    }
		//    string sGroup;
		//    if (0 == stats.MessagesThisFile )
		//    {
		//        // first file has special pattern...since rolling doesn't occur when message
		//        // is logged, rather before next message is logged.
		//        if (stats.NumberOfFileRolls <= 1 )
		//        {
		//            return null;   
		//        }
		//        // Use backup files from previous round.  The minus 2 is because we have already
		//        // rolled, and the first round uses null instead of the string
		//        sGroup = GetBackupGroup( sBackupGroups, stats.NumberOfFileRolls-2 );
		//    }
		//    else
		//    {
		//        sGroup = GetBackupGroup( sBackupGroups, stats.NumberOfFileRolls-1 );
		//    }
		//    return MakeBackupFileEntriesFromBackupGroup( sGroup, stats.MaximumFileSize );
		//}

		/// <summary>
		/// Builds a collection of file entries based on the file names
		/// specified in a groups string and the max file size from the
		/// stats object
		/// </summary>
		/// <param name="sBackupGroups"></param>
		/// <param name="stats"></param>
		/// <returns></returns>
		private static RollFileEntry[] MakeBackupFileEntriesForPostCondition(string sBackupGroups, RollingStats stats)
		{
			if (0 == stats.NumberOfFileRolls)
			{
				return null; // first round has no previous backups
			}
			string sGroup = GetBackupGroup(sBackupGroups, stats.NumberOfFileRolls - 1);
			return MakeBackupFileEntriesFromBackupGroup(sGroup, stats.MaximumFileSize);
		}
		/// <summary>
		/// The stats are used to keep track of progress while we are algorithmically
		/// generating a table of pre/post condition tests for file rolling.
		/// </summary>
		/// <param name="sTestMessage"></param>
		/// <returns></returns>
		private static RollingStats InitializeStats(string sTestMessage)
		{
			RollingStats rollingStats = new RollingStats();

			rollingStats.TotalMessageLength = TotalMessageLength(sTestMessage);
			rollingStats.MessagesPerFile = MessagesPerFile(rollingStats.TotalMessageLength);
			rollingStats.MessagesThisFile = 0;
			rollingStats.NumberOfFileRolls = 0;

			return rollingStats;
		}
		/// <summary>
		/// Builds a collection of file entries based on the file names
		/// specified in a groups string and the max file size from the
		/// stats object
		/// </summary>
		/// <param name="sBackupGroups"></param>
		/// <param name="stats"></param>
		/// <returns></returns>
		private RollFileEntry[] MakeBackupFileEntriesForPreCondition( string sBackupGroups, RollingStats stats )
		{
			if (0 == stats.NumberOfFileRolls )
			{
				return null;	// first round has no previous backups
			}
			string sGroup;
			if (0 == stats.MessagesThisFile )
			{
				// first file has special pattern...since rolling doesn't occur when message
				// is logged, rather before next message is logged.
				if (stats.NumberOfFileRolls <= 1 )
				{
					return null;   
				}
				// Use backup files from previous round.  The minus 2 is because we have already
				// rolled, and the first round uses null instead of the string
				sGroup = GetBackupGroup( sBackupGroups, stats.NumberOfFileRolls-2 );
			}
			else
			{
				sGroup = GetBackupGroup( sBackupGroups, stats.NumberOfFileRolls-1 );
			}
			return MakeBackupFileEntriesFromBackupGroup( sGroup, stats.MaximumFileSize );
		}