private void Directory_DeleteEmptySubdirectories(bool isNetwork)
        {
            UnitTestConstants.PrintUnitTestHeader(isNetwork);

            var tempPath = System.IO.Path.GetTempPath();

            if (isNetwork)
            {
                tempPath = Alphaleonis.Win32.Filesystem.Path.LocalToUnc(tempPath);
            }


            using (var rootDir = new TemporaryDirectory(tempPath, MethodBase.GetCurrentMethod().Name))
            {
                var folder = System.IO.Directory.CreateDirectory(System.IO.Path.Combine(rootDir.Directory.FullName, "Source Folder"));
                Console.WriteLine("\nInput Directory Path: [{0}]", folder.FullName);


                const int maxDepth             = 10;
                const int totalDirectories     = maxDepth * maxDepth + maxDepth;      // maxDepth = 10: 110 directories and 110 files.
                const int emptyDirectories     = maxDepth * maxDepth / 2;             // 50 empty directories.
                const int remainingDirectories = totalDirectories - emptyDirectories; // 60 remaining directories.

                var searchPattern = Alphaleonis.Win32.Filesystem.Path.WildcardStarMatchAll;
                const Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions enumOptionsFolder = Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions.Folders | Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions.Recursive | Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions.ContinueOnException;
                const Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions enumOptionsFile   = Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions.Files | Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions.Recursive | Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions.ContinueOnException;


                UnitTestConstants.CreateDirectoriesAndFiles(folder.FullName, maxDepth, false, false, true);

                var dirs0  = Alphaleonis.Win32.Filesystem.Directory.CountFileSystemObjects(folder.FullName, searchPattern, enumOptionsFolder);
                var files0 = Alphaleonis.Win32.Filesystem.Directory.CountFileSystemObjects(folder.FullName, searchPattern, enumOptionsFile);
                Console.WriteLine("\n\tCounted Directories: [{0}]  Empty Directories: [{1}]", dirs0, emptyDirectories);
                Console.WriteLine("\tCounted Files      : [{0}]", files0);


                Alphaleonis.Win32.Filesystem.Directory.DeleteEmptySubdirectories(folder.FullName, true);


                Assert.IsTrue(System.IO.Directory.Exists(folder.FullName), "The root directory does not exist, but is expected to.");

                var dirs1  = Alphaleonis.Win32.Filesystem.Directory.CountFileSystemObjects(folder.FullName, searchPattern, enumOptionsFolder);
                var files1 = Alphaleonis.Win32.Filesystem.Directory.CountFileSystemObjects(folder.FullName, searchPattern, enumOptionsFile);
                Console.WriteLine("\n\tCounted Directories: [{0}]", dirs1);
                Console.WriteLine("\tCounted Files      : [{0}]", files1);

                Assert.AreNotEqual(dirs0, dirs1, "The number of directories are equal, but are expected not to.");
                Assert.AreEqual(remainingDirectories, dirs1, "The number of directories are not equal, but are expected to be.");
                Assert.AreEqual(files0, files1, "The number of files are not equal, but are expected to be.");
                Assert.AreEqual(totalDirectories, emptyDirectories + remainingDirectories, "The number of directories are not equal, but are expected to be.");
            }

            Console.WriteLine();
        }
        private void AlphaFS_Directory_DeleteEmptySubdirectories(bool isNetwork)
        {
            using (var tempRoot = new TemporaryDirectory(isNetwork))
            {
                const int maxDepth             = 10;
                const int totalDirectories     = maxDepth * maxDepth + maxDepth;      // maxDepth = 10: 110 directories and 110 files.
                const int emptyDirectories     = maxDepth * maxDepth / 2;             // 50 empty directories.
                const int remainingDirectories = totalDirectories - emptyDirectories; // 60 remaining directories.

                var folder = tempRoot.CreateRecursiveTree(maxDepth);

                Console.WriteLine("Input Directory Path: [{0}]", folder.FullName);


                var searchPattern = Alphaleonis.Win32.Filesystem.Path.WildcardStarMatchAll;
                const Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions enumOptionsFolder = Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions.Folders | Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions.Recursive | Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions.ContinueOnException;
                const Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions enumOptionsFile   = Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions.Files | Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions.Recursive | Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions.ContinueOnException;


                var dirs0  = Alphaleonis.Win32.Filesystem.Directory.CountFileSystemObjects(folder.FullName, searchPattern, enumOptionsFolder);
                var files0 = Alphaleonis.Win32.Filesystem.Directory.CountFileSystemObjects(folder.FullName, searchPattern, enumOptionsFile);
                Console.WriteLine("\n\tCounted Directories: [{0}]  Empty Directories: [{1}]", dirs0, emptyDirectories);
                Console.WriteLine("\tCounted Files      : [{0}]", files0);


                Alphaleonis.Win32.Filesystem.Directory.DeleteEmptySubdirectories(folder.FullName, true);


                Assert.IsTrue(System.IO.Directory.Exists(folder.FullName), "The root directory does not exist, but is expected to.");

                var dirs1  = Alphaleonis.Win32.Filesystem.Directory.CountFileSystemObjects(folder.FullName, searchPattern, enumOptionsFolder);
                var files1 = Alphaleonis.Win32.Filesystem.Directory.CountFileSystemObjects(folder.FullName, searchPattern, enumOptionsFile);
                Console.WriteLine("\n\tCounted Directories: [{0}]", dirs1);
                Console.WriteLine("\tCounted Files      : [{0}]", files1);

                Assert.AreNotEqual(dirs0, dirs1, "The number of directories are equal, but are expected not to.");
                Assert.AreEqual(remainingDirectories, dirs1, "The number of directories are not equal, but are expected to be.");
                Assert.AreEqual(files0, files1, "The number of files are not equal, but are expected to be.");
                Assert.AreEqual(totalDirectories, emptyDirectories + remainingDirectories, "The number of directories are not equal, but are expected to be.");
            }

            Console.WriteLine();
        }
        private void Test_ContinueOnAccessDeniedExceptionUsingErrorFilter(string inputPath)
        {
            var       gotException   = false;
            const int exceptionCatch = 10;
            var       exceptionCount = 0;


#if NET35
            var abortEnumeration = false;


            var filters = new Alphaleonis.Win32.Filesystem.DirectoryEnumerationFilters
            {
                // Filter to decide whether to recurse into subdirectories.
                RecursionFilter = fsei =>
                {
                    // Return true to continue recursion, false to skip.
                    return(!abortEnumeration);
                },


                // Filter to process Exception handling.
                ErrorFilter = delegate(int errorCode, string errorMessage, string pathProcessed)
                {
                    if (abortEnumeration)
                    {
                        return(true);
                    }


                    gotException = errorCode == Alphaleonis.Win32.Win32Errors.ERROR_ACCESS_DENIED;
                    if (gotException)
                    {
                        exceptionCount++;

                        if (exceptionCount == exceptionCatch)
                        {
                            abortEnumeration = true;
                        }
                    }


                    // Report Exception.
                    Console.WriteLine("\t#{0:N0}\t({1}) {2}: [{3}]", exceptionCount, errorCode, errorMessage, pathProcessed);


                    // Return true to continue, false to throw the Exception.
                    return(gotException);
                }
            };
#else
            var cancelSource = new CancellationTokenSource();


            var filters = new Alphaleonis.Win32.Filesystem.DirectoryEnumerationFilters
            {
                // Used to abort the enumeration.
                CancellationToken = cancelSource.Token,


                // Filter to process Exception handling.
                ErrorFilter = delegate(int errorCode, string errorMessage, string pathProcessed)
                {
                    gotException = errorCode == Alphaleonis.Win32.Win32Errors.ERROR_ACCESS_DENIED;
                    if (gotException)
                    {
                        exceptionCount++;

                        if (exceptionCount == exceptionCatch)
                        {
                            cancelSource.Cancel();
                        }
                    }


                    // Report Exception.
                    Console.WriteLine("\t#{0:N0}\t({1}) {2}: [{3}]", exceptionCount, errorCode, errorMessage, pathProcessed);


                    // Return true to continue, false to throw the Exception.
                    return(gotException);
                }
            };
#endif


            const Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions dirEnumOptions = Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions.Recursive;

            var fsoCount = Alphaleonis.Win32.Filesystem.Directory.EnumerateFileSystemEntryInfos <string>(inputPath, dirEnumOptions, filters).Count();


            Console.WriteLine("\n\tFile system objects counted: {0:N0}", fsoCount);


            Assert.IsTrue(fsoCount > 0, "No file system entries enumerated, but it is expected.");

            Assert.IsTrue(gotException, "The Exception is not caught, but it is expected.");

            Assert.AreEqual(exceptionCatch, exceptionCount, "The number of caught Exceptions does not match, but it is expected.");
        }
      private void Test_DirectoryEnumerationFilters(string inputPath)
      {
         bool gotException;

         var findExtensions = new[] {".txt", ".ini", ".exe"};
         var skipFolders = new[] {"assembly", "WinSxS"};

         Console.WriteLine("Extensions to search for: {0}", string.Join(" | ", findExtensions));
         Console.WriteLine("Root directories to skip: {0}\\{1}, {0}\\{2}", inputPath, skipFolders[0], skipFolders[1]);
         Console.WriteLine();


         var exceptionCount = 0;
         var foundExt1 = 0;
         var foundExt2 = 0;
         var foundExt3 = 0;
         var foundExt1Done = false;
         var foundExt2Done = false;
         var foundExt3Done = false;


#if NET35
         var abortEnumeration = false;


         var filters = new Alphaleonis.Win32.Filesystem.DirectoryEnumerationFilters
         {
            // Filter to decide whether to recurse into subdirectories.
            RecursionFilter = fsei =>
            {
               if (abortEnumeration)
                  return false;


               // Return true to continue recursion, false to skip.
               return !skipFolders.Any(found => found.Equals(fsei.FileName, StringComparison.OrdinalIgnoreCase));
            },


            // Filter to process Exception handling.
            ErrorFilter = delegate(int errorCode, string errorMessage, string pathProcessed)
            {
               if (abortEnumeration)
                  return true;


               gotException = errorCode == Alphaleonis.Win32.Win32Errors.ERROR_ACCESS_DENIED;

               Console.WriteLine("\t#{0:N0}\t\t({1}) {2}: [{3}]", ++exceptionCount, errorCode, errorMessage, pathProcessed);


               // Return true to continue, false to throw the Exception.
               return gotException;
            },


            // Filter to in-/exclude file system entries during the enumeration.
            InclusionFilter = fsei =>
            {
               if (abortEnumeration)
                  return false;


               var fileExtension = fsei.Extension;

               var gotMatch = findExtensions.Any(found => found.Equals(fileExtension, StringComparison.OrdinalIgnoreCase));
               if (gotMatch)
               {
                  if (!foundExt1Done && fileExtension == findExtensions[0])
                  {
                     foundExt1++;
                     foundExt1Done = foundExt1 == 3;
                     Console.WriteLine("\t#{0:N0}\t\t[{1}]", foundExt1, fsei.FullPath);
                  }

                  else if (!foundExt2Done && fileExtension == findExtensions[1])
                  {
                     foundExt2++;
                     foundExt2Done = foundExt2 == 3;
                     Console.WriteLine("\t#{0:N0}\t\t[{1}]", foundExt2, fsei.FullPath);
                  }

                  else if (!foundExt3Done && fileExtension == findExtensions[2])
                  {
                     foundExt3++;
                     foundExt3Done = foundExt3 == 3;
                     Console.WriteLine("\t#{0:N0}\t\t[{1}]", foundExt3, fsei.FullPath);
                  }
               }


               // Abort the enumeration.
               if (foundExt1Done && foundExt2Done && foundExt3Done)
                  abortEnumeration = true;


               return gotMatch;
            }
         };
#else
         var cancelSource = new CancellationTokenSource();


         var filters = new Alphaleonis.Win32.Filesystem.DirectoryEnumerationFilters
         {
            // Used to abort the enumeration.
            CancellationToken = cancelSource.Token,


            // Filter to decide whether to recurse into subdirectories.
            RecursionFilter = fsei =>
            {
               // Return true to continue recursion, false to skip.
               return !skipFolders.Any(found => found.Equals(fsei.FileName, StringComparison.OrdinalIgnoreCase));
            },


            // Filter to process Exception handling.
            ErrorFilter = delegate(int errorCode, string errorMessage, string pathProcessed)
            {
               gotException = errorCode == Alphaleonis.Win32.Win32Errors.ERROR_ACCESS_DENIED;

               Console.WriteLine("\t#{0:N0}\t\t({1}) {2}: [{3}]", ++exceptionCount, errorCode, errorMessage, pathProcessed);


               // Return true to continue, false to throw the Exception.
               return gotException;
            },


            // Filter to in-/exclude file system entries during the enumeration.
            InclusionFilter = fsei =>
            {
               var fileExtension = fsei.Extension;

               var gotMatch = findExtensions.Any(found => found.Equals(fileExtension, StringComparison.OrdinalIgnoreCase));
               if (gotMatch)
               {
                  if (!foundExt1Done && fileExtension == findExtensions[0])
                  {
                     foundExt1++;
                     foundExt1Done = foundExt1 == 3;
                     Console.WriteLine("\t#{0:N0}\t\t[{1}]", foundExt1, fsei.FullPath);
                  }

                  else if (!foundExt2Done && fileExtension == findExtensions[1])
                  {
                     foundExt2++;
                     foundExt2Done = foundExt2 == 3;
                     Console.WriteLine("\t#{0:N0}\t\t[{1}]", foundExt2, fsei.FullPath);
                  }

                  else if (!foundExt3Done && fileExtension == findExtensions[2])
                  {
                     foundExt3++;
                     foundExt3Done = foundExt3 == 3;
                     Console.WriteLine("\t#{0:N0}\t\t[{1}]", foundExt3, fsei.FullPath);
                  }
               }


               // Abort the enumeration.
               if (foundExt1Done && foundExt2Done && foundExt3Done)
                  cancelSource.Cancel();


               return gotMatch;
            }
         };
#endif


         const Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions dirEnumOptions = Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions.Files | Alphaleonis.Win32.Filesystem.DirectoryEnumerationOptions.Recursive;

         var fsoCount = Alphaleonis.Win32.Filesystem.Directory.EnumerateFileSystemEntryInfos<string>(inputPath, dirEnumOptions, filters).Count();
         
         
         Console.WriteLine("\n\tFile system objects counted: {0:N0}", fsoCount);


         Assert.IsTrue(fsoCount > 0, "No files enumerated, but it is expected.");

         Assert.IsTrue(foundExt1 > 0, "No " + findExtensions[0] + " files enumerated, but it is expected.");
         Assert.IsTrue(foundExt2 > 0, "No " + findExtensions[1] + " files enumerated, but it is expected.");
         Assert.IsTrue(foundExt3 > 0, "No " + findExtensions[2] + " files enumerated, but it is expected.");


         Console.WriteLine();
      }