//
        // Finds the root path of the review
        //
        private static string FindReviewRootPath(string[] reviewContent, Logging logger)
        {
            // Spin through and get the root
            string rootPath = string.Empty;

            foreach (string thisEntry in reviewContent)
            {
                // Get the root of this file
                string thisRoot = Svn.GetRoot(thisEntry);
                if (thisRoot == null)
                {
                    continue;
                }

                // We have a root, send it back
                logger.Log("Calculated root path is '{0}'", thisRoot);
                return(thisRoot);
            }

            // If we got here, no root
            logger.Log("Unable to calculate the root path for the review - is SVN installed");
            MessageBox.Show("Unable to find a working SVN root directly, are the SVN command line tools installed?", "Unable to raise review", MessageBoxButtons.OK, MessageBoxIcon.Error);

            // Return nothing
            return(null);
        }
        //
        // Rejects the files in the list that are not valid
        //
        private static string[] RejectInvalidFiles(string[] reviewContent, string rootPath, Logging logger)
        {
            // Create a list to keep track of rejected files
            List <string> rejectedFiles = new List <string>();

            // Check all the entries to review are valid
            reviewContent = reviewContent.Where(x =>
            {
                // Get the root path in which this repostory lives
                string thisRoot = Svn.GetRoot(x);

                // If we don't have a root it's not source controlled so bail
                if (thisRoot == null)
                {
                    rejectedFiles.Add(x);
                    return(false);
                }

                // If we're under the same root we're fine
                bool underSameRoot = rootPath.Equals(thisRoot);
                if (underSameRoot == false)
                {
                    rejectedFiles.Add(x);
                    return(false);
                }

                // Return that we should keep this file
                return(true);
            }).ToArray();

            // If we have any rejected files, let the user know
            if (rejectedFiles.Count != 0)
            {
                logger.Log("Some files will not be reviewed");

                StringBuilder errorMessage = new StringBuilder("Unable to include the following files for review\n");
                foreach (string thisError in rejectedFiles)
                {
                    string stringToShow = Paths.TruncateLongPath(thisError);
                    errorMessage.Append("- " + stringToShow + "\n");

                    logger.Log(" * {0}", thisError);
                }

                MessageBox.Show(errorMessage.ToString(), "Warning when raising review", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            // Do we have any files left?
            if (reviewContent.Length == 0)
            {
                MessageBox.Show("No content was found that could actually be reviewed", "Unable to raise review", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            // Return the updated files
            return(reviewContent.Count() == 0 ? null : reviewContent);
        }