/// <summary>
        /// Inner method used to implement the setup operation.  
        /// </summary>
        protected void InnerSetup(Config config)
        {
            // if needed, clear the prior state.
            if (setupPerformed)
                Clear();

            // record the given configuration
            this.config = config;
            excludedFileSet = new System.Collections.Specialized.StringCollection();
            excludedFileSet.AddRange(config.excludeFileNamesSet.ToArray());

            string dirPath = config.dirPath;

            // try to add a DirectoryEntryInfo record for each of the files that are in the directory
            try
            {
                DirectoryEntryInfo basePathInfo = new DirectoryEntryInfo(dirPath);

                if (basePathInfo.Exists)
                {
                    if (basePathInfo.IsFile)
                        throw new SetupFailureException(Utils.Fcns.CheckedFormat("target path '{0}' does not specify a directory.", dirPath));
                }
                else
                {
                    if (config.createDirectoryIfNeeded)
                        System.IO.Directory.CreateDirectory(dirPath);
                    else
                        throw new SetupFailureException(Utils.Fcns.CheckedFormat("target path '{0}' does not exist.", dirPath));
                }

                // directory exists or has been created - now scan it and record each of the entries that are found therein
                DirectoryInfo dirInfo = new DirectoryInfo(dirPath);
                FileSystemInfo [] directoryFSIArray = dirInfo.GetFileSystemInfos();

                foreach (FileSystemInfo fsi in directoryFSIArray)
                {
                    string path = fsi.FullName;
                    string name = fsi.Name;

                    if (!excludedFileSet.Contains(name) && !excludedFileSet.Contains(path))
                        AddDirEntry(path, true);
                }

                if (numBadDirEntries != 0)
                    logger.Error.Emit("Setup Failure: There are bad directory entries in dir '{0}'", dirPath);
            }
            catch (SetupFailureException sfe)
            {
                SetSetupFaultCode(sfe.Message);
            }
            catch (System.Exception ex)
            {
                SetSetupFaultCode(Utils.Fcns.CheckedFormat("Setup Failure: encountered unexpected exception '{0}' while processing dir '{1}'", ex.Message, dirPath));
            }

            if (!SetupFailed)
            {
                // perform an additional set of tests
                if (string.IsNullOrEmpty(config.fileNamePrefix) || string.IsNullOrEmpty(config.fileNameSuffix))
                    SetSetupFaultCode("Setup Failure: Invalid file name fields in configuration");
                else if (config.advanceRules.fileAgeLimitInSec < 0.0)
                    SetSetupFaultCode("Setup Failure: Config: advanceRules.fileAgeLimitInSec is negative");
                else if (config.purgeRules.dirNumFilesLimit > 0 && config.purgeRules.dirNumFilesLimit < ConfigPurgeNumFilesMinValue)
                    SetSetupFaultCode("Setup Failure: Config: purgeRules.dirNumFilesLimit is too small");
                else if (config.purgeRules.dirNumFilesLimit > 0 && config.purgeRules.dirNumFilesLimit > ConfigPurgeNumFilesMaxValue)
                    SetSetupFaultCode("Setup Failure: Config: purgeRules.dirNumFilesLimit is too large");
                else if (config.purgeRules.dirTotalSizeLimit < 0)
                    SetSetupFaultCode("Setup Failure: Config: purgeRules.dirTotalSizeLimit is negative");
                else if (config.purgeRules.fileAgeLimitInSec < 0.0)
                    SetSetupFaultCode("Setup Failure: Config: purgeRules.maxFileAgeLimitInSec is negative");
            }

            DirectoryEntryInfo activeFileInfo = new DirectoryEntryInfo();

            if (!SetupFailed)
            {
                switch (config.fileNamePattern)
                {
                case FileNamePattern.ByDate:				numFileNumberDigits = 0; break;
                case FileNamePattern.Numeric2DecimalDigits:	numFileNumberDigits = 2; maxFileNumber = 100; break;
                case FileNamePattern.Numeric3DecimalDigits:	numFileNumberDigits = 3; maxFileNumber = 1000; break;
                case FileNamePattern.Numeric4DecimalDigits:	numFileNumberDigits = 4; maxFileNumber = 10000; break;
                default: SetSetupFaultCode("Setup Failure: Invalid file name pattern in configuration"); break;
                }

                // go through the directory file info entries (acquired above) from newest to oldest
                //	and retain the newest valid file that matches the name pattern for this content
                //	manager.  This file will become the initial active file.

                activeFileEntryID = DirEntryID_Invalid;
                activeFileNumber = 0;
                bool matchFound = false;

                IList<Int64> itemKeys = dirEntryIDListSortedByCreatedFTimeUtc.Keys;
                IList<List<int>> itemValues = dirEntryIDListSortedByCreatedFTimeUtc.Values;

                for (int idx = dirEntryIDListSortedByCreatedFTimeUtc.Count - 1; !matchFound && idx >= 0; idx--)
                {
                    Int64 itemFTime = itemKeys[idx];
                    List<int> itemEntryIDList = itemValues[idx];

                    foreach (int itemEntryID in itemEntryIDList)
                    {
                        activeFileEntryID = itemEntryID;

                        if (IsDirEntryIDValid(activeFileEntryID))
                            activeFileInfo = dirEntryList[activeFileEntryID];
                        else
                        {
                            activeFileInfo.Clear();
                            Utils.Asserts.TakeBreakpointAfterFault("Setup: entry ID in ListSortedByCreated is not valid");
                            continue;
                        }

                        // verify that the entry is a file
                        if (!activeFileInfo.IsFile)
                        {
                            Utils.Asserts.TakeBreakpointAfterFault("Setup: entry ID in ListSortedByCreated is not a file");
                            continue;
                        }

                        // divide the name into prefix, middle and suffix fields

                        string fileName = activeFileInfo.Name;
                        bool fileNameIsValidMatch = true;

                        int fileNamePrefixLen = config.fileNamePrefix.Length;
                        int fileNameSuffixLen = config.fileNameSuffix.Length;

                        int split1Idx = Math.Min(fileNamePrefixLen, fileName.Length);   // prevent attempting to call Substring with a second arg that is beyond the end of the string.
                        string prefix = fileName.Substring(0, split1Idx);
                        string rest = fileName.Substring(split1Idx);
                        int restLen = rest.Length;

                        string middle = string.Empty, suffix = string.Empty;

                        if (restLen >= fileNameSuffixLen)
                        {
                            int splitPoint = restLen - fileNameSuffixLen;

                            middle = rest.Substring(0, splitPoint);
                            suffix = rest.Substring(splitPoint);
                        }
                        else
                        {
                            // this file name does not match requirements - exclude from search for current active file
                            fileNameIsValidMatch = false;
                        }

                        // test if the prefix and suffix's match
                        if (prefix != config.fileNamePrefix || suffix != config.fileNameSuffix)
                            fileNameIsValidMatch = false;

                        // test if the middle is valid
                        if (numFileNumberDigits > 0)
                        {
                            int testFileNumber = -1;
                            bool match = int.TryParse(middle, out testFileNumber);

                            if (testFileNumber >= 0 && middle.Length == numFileNumberDigits && match)
                                activeFileNumber = testFileNumber;
                            else
                                fileNameIsValidMatch = false;
                        }
                        else
                        {
                            // for FileNamePattern.ByDate files, we assume that the middle is valid if it is not empty
                            if (middle.Length == 0)
                                fileNameIsValidMatch = false;
                        }

                        matchFound = fileNameIsValidMatch;
                        if (matchFound)
                            break;
                    }
                }

                if (!matchFound && dirEntryIDListSortedByCreatedFTimeUtc.Count != 0)
                    logger.Warning.Emit("Setup Warning: no valid active file found in non-empty directory '{0}'", dirPath);
            }

            if (!SetupFailed && config.enableAutomaticCleanup)
            {
                for (int limit = 0; IsDirectoryCleanupNeeded && (limit < config.maxAutoCleanupDeletes); limit++)
                    PerformIncrementalCleanup();
            }

            if (SetupFailed)
            {
                logger.Error.Emit("Directory is not usable: path:'{0}' fault:'{1}'", dirPath, setupFaultCode);
            }
            else
            {
                logger.Debug.Emit("Directory is usable: path:'{0}' number of files:{1} active file:'{2}'",
                                            dirPath, dirEntryIDListSortedByName.Count, activeFileInfo.Name);
            }

            setupPerformed = true;
        }