public void StageFiles(StagedFileType FileType, DirectoryReference InputDir, string Wildcard = "*", bool bRecursive = true, string[] ExcludeWildcards = null, StagedDirectoryReference NewPath = null, bool bAllowNone = false, bool bRemap = true, string NewName = null, bool bAllowNotForLicenseesFiles = true, bool bStripFilesForOtherPlatforms = true, bool bConvertToLower = false)
    {
        int FilesAdded = 0;

        if (DirectoryReference.Exists(InputDir))
        {
            FileReference[] InputFiles = CommandUtils.FindFiles(Wildcard, bRecursive, InputDir);

            HashSet <FileReference> ExcludeFiles = new HashSet <FileReference>();
            if (ExcludeWildcards != null)
            {
                foreach (string ExcludeWildcard in ExcludeWildcards)
                {
                    ExcludeFiles.UnionWith(CommandUtils.FindFiles(ExcludeWildcard, bRecursive, InputDir));
                }
            }

            foreach (FileReference InputFile in InputFiles)
            {
                if (ExcludeFiles.Contains(InputFile))
                {
                    continue;
                }

                if (bStripFilesForOtherPlatforms && !bIsCombiningMultiplePlatforms && IsFileForOtherPlatform(InputFile))
                {
                    continue;
                }

                // Get the staged location for this file
                StagedFileReference Dest;
                if (NewPath != null)
                {
                    // If the specified a new directory, first we deal with that, then apply the other things. This is used to collapse the sandbox, among other things.
                    Dest = StagedFileReference.Combine(NewPath, InputFile.MakeRelativeTo(InputDir));
                }
                else if (InputFile.IsUnderDirectory(ProjectRoot))
                {
                    // Project relative file
                    Dest = StagedFileReference.Combine(RelativeProjectRootForStage, InputFile.MakeRelativeTo(ProjectRoot));
                }
                else if (InputFile.IsUnderDirectory(LocalRoot))
                {
                    // Engine relative file
                    Dest = new StagedFileReference(InputFile.MakeRelativeTo(LocalRoot));
                }
                else
                {
                    throw new AutomationException("Can't deploy {0} because it doesn't start with {1} or {2}", InputFile, ProjectRoot, LocalRoot);
                }

                if (!bAllowNotForLicenseesFiles && (Dest.ContainsName(new FileSystemName("NotForLicensees")) || Dest.ContainsName(new FileSystemName("NoRedist"))))
                {
                    continue;
                }

                if (NewName != null)
                {
                    Dest = StagedFileReference.Combine(Dest.Directory, NewName);
                }

                if (bRemap)
                {
                    Dest = StageTargetPlatform.Remap(Dest);
                }

                if (bConvertToLower)
                {
                    Dest = Dest.ToLowerInvariant();
                }

                FilesToStage.Add(FileType, Dest, InputFile);

                FilesAdded++;
            }
        }

        if (FilesAdded == 0 && !bAllowNone && !bIsCombiningMultiplePlatforms)
        {
            throw new AutomationException(ExitCode.Error_StageMissingFile, "No files found to deploy for {0} with wildcard {1} and exclusions {2}", InputDir, Wildcard, String.Join(", ", ExcludeWildcards));
        }
    }