private static Stats SignAssemblies(Options options)
        {
            int signedFiles = 0;
              int referenceFixes = 0;

              IEnumerable<string> filesToSign = null;

              if (!string.IsNullOrWhiteSpace(options.InputDirectory))
              {
            filesToSign = Directory.GetFiles(options.InputDirectory, "*.*", SearchOption.AllDirectories)
              .Where(f => Path.GetExtension(f).Equals(".exe", StringComparison.OrdinalIgnoreCase) ||
                      Path.GetExtension(f).Equals(".dll", StringComparison.OrdinalIgnoreCase));
              }
              else
              {
            // We can assume from validation that there will be a single file.
            filesToSign = new string[] { options.AssemblyFile };
              }

              foreach (var filePath in filesToSign)
              {
            if (SignSingleAssembly(filePath, options.KeyFile, options.OutputDirectory))
            {
              signedFiles++;
            }
              }

              var referencesToFix = new List<string>(filesToSign);
              foreach (var filePath in filesToSign)
              {
            // Go through all the references excluding the file we are working on.
            foreach (var referencePath in referencesToFix.Where(r => !r.Equals(filePath)))
            {
              if (FixSingleAssemblyReference(filePath, referencePath))
              {
            referenceFixes++;
              }
            }
              }

              return new Stats()
              {
            NumberOfSignedFiles = signedFiles,
            NumberOfFixedReferences = referenceFixes
              };
        }
        private static Stats SignAssemblies(Options options)
        {
            int signedFiles = 0;
              int referenceFixes = 0;

              HashSet<string> filesToSign = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

              if (!string.IsNullOrWhiteSpace(options.InputDirectory))
              {
            foreach (var inputDir in options.InputDirectory.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
            {
              foreach (var file in Directory.GetFiles(inputDir, "*.*", SearchOption.AllDirectories)
            .Where(f => Path.GetExtension(f).Equals(".exe", StringComparison.OrdinalIgnoreCase) ||
                        Path.GetExtension(f).Equals(".dll", StringComparison.OrdinalIgnoreCase)))
              {
            filesToSign.Add(file);
              }
            }
              }
              else
              {
            // We can assume from validation that there will be a single file.
            filesToSign.Add(options.AssemblyFile);
              }

              var processedAssemblyPaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
              var signedAssemblyPaths = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

              foreach (var filePath in filesToSign)
              {
            var signedAssembly = SignSingleAssembly(filePath, options.KeyFile, options.OutputDirectory, options.Password);
            if (signedAssembly != null)
            {
              processedAssemblyPaths.Add(signedAssembly.FilePath);
              signedAssemblyPaths.Add(signedAssembly.FilePath);
              signedFiles++;
            }
            else
            {
              processedAssemblyPaths.Add(filePath);
            }
              }

              var referencesToFix = new HashSet<string>(processedAssemblyPaths, StringComparer.OrdinalIgnoreCase);
              foreach (var filePath in processedAssemblyPaths)
              {
            // Go through all the references excluding the file we are working on.
            foreach (var referencePath in referencesToFix.Where(r => !r.Equals(filePath)))
            {
              if (FixSingleAssemblyReference(filePath, referencePath, options.KeyFile, options.Password, filesToSign.Select(f => Path.GetDirectoryName(f)).Distinct().ToArray()))
              {
            referenceFixes++;
              }
            }
              }

              // Remove all InternalsVisibleTo attributes without public keys from the processed assemblies. Signed assemblies cannot have unsigned friend assemblies.
              foreach (var filePath in signedAssemblyPaths)
              {
            if (RemoveInvalidFriendAssemblyReferences(filePath, options.KeyFile, options.Password, filesToSign.Select(f => Path.GetDirectoryName(f)).Distinct().ToArray()))
            {
              referenceFixes++;
            }
              }

              return new Stats()
              {
            NumberOfSignedFiles = signedFiles,
            NumberOfFixedReferences = referenceFixes
              };
        }