public void ReplaceInFiles(string rootDir, string include,string exclude,IDictionary<string,string>replacements,StringBuilder logger = null)
        {
            if (string.IsNullOrEmpty(rootDir)) { throw new ArgumentNullException("rootDir"); }
            if (!Directory.Exists(rootDir)) { throw new ArgumentException(string.Format("rootDir doesn't exist at [{0}]", rootDir)); }

            string rootDirFullPath = Path.GetFullPath(rootDir);

            // search for all include files
            List<string> pathsToInclude = new List<string>();
            List<string> pathsToExclude = new List<string>();

            if (!string.IsNullOrEmpty(include)) {
                string[] includeParts = include.Split(';');
                foreach (string includeStr in includeParts) {
                    var results = RobustReplacer.Search(rootDirFullPath, includeStr);
                    foreach (var result in results) {
                        if (!pathsToInclude.Contains(result)) {
                            pathsToInclude.Add(result);
                        }
                    }
                }
            }

            if (!string.IsNullOrEmpty(exclude)) {
                string[] excludeParts = exclude.Split(';');
                foreach (string excludeStr in excludeParts) {
                    var results = RobustReplacer.Search(rootDirFullPath, excludeStr);
                    foreach (var result in results) {
                        if (!pathsToExclude.Contains(result)) {
                            pathsToExclude.Add(result);
                        }
                    }
                }
            }

            int numFilesExcluded = pathsToInclude.RemoveAll(p => pathsToExclude.Contains(p));
            LogMessageLine(logger,"Number of files excluded based on pattern: [{0}]", numFilesExcluded);

            foreach (string file in pathsToInclude) {
                string fileFullPath = Path.GetFullPath(file);
                bool modified = false;

                using (var fileStream = File.Open(fileFullPath, FileMode.Open, FileAccess.ReadWrite)) {
                    using (var replacer = new TokenReplacer(fileStream)) {
                        foreach (string key in replacements.Keys) {
                            modified |= replacer.Replace(key, replacements[key]);
                        }
                    }

                    fileStream.Flush();
                }

                if (modified) {
                    LogMessageLine(logger,"Updating text after replacements in file [{0}]", fileFullPath);
                }
                else {
                    LogMessageLine(logger,"Not writing out file because no replacments detected [{0}]", fileFullPath);
                }
            }
        }
        public static bool ProcessConditionalRegionsInFile(string fileName, string startToken, string endToken, bool isConditionSatisfied)
        {
            bool modified;

            using (var file = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite))
            {
                using (var replacer = new TokenReplacer(file))
                {
                    modified = replacer.ProcessConditionalRegion(startToken, endToken, isConditionSatisfied);
                }

                file.Flush();
            }

            return modified;
        }
        public static bool ReplaceInFile(string fileName, byte[] tokenBytes, byte[] replaceWithBytes)
        {
            bool modified;

            using (var file = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite))
            {
                using (var replacer = new TokenReplacer(file))
                {
                    modified = replacer.Replace(tokenBytes, replaceWithBytes);
                }

                file.Flush();
            }

            return modified;
        }
        public static bool ReplaceInFile(string fileName, string token, string replaceWith, Encoding encoding)
        {
            bool modified;

            using (var file = File.Open(fileName, FileMode.Open, FileAccess.ReadWrite))
            {
                using (var replacer = new TokenReplacer(file))
                {
                    modified = replacer.Replace(token, replaceWith, encoding);
                }

                file.Flush();
            }

            return modified;
        }