Exemplo n.º 1
0
        public void Cannot_merge_Mark_as_a_conflict()
        {
            string userText    = Helper.GetResource(resourcePrefix + "ThreeOtherLines2.txt");
            string prevGenText = Helper.GetResource(resourcePrefix + "ThreeLines.txt");
            string newGenText  = Helper.GetResource(resourcePrefix + "ThreeOtherLines.txt");

            SlyceMergeResult mergeObject = SlyceMerge.Perform3wayDiff(userText, prevGenText, newGenText, out merged);

            Assert.AreEqual(TypeOfDiff.Conflict, mergeObject.DiffType, "Cannot merge. Mark as conflicted.");
        }
Exemplo n.º 2
0
        public void The_merged_equals_3CrLfs_input()
        {
            string userText    = Environment.NewLine + Environment.NewLine + Environment.NewLine;
            string prevGenText = userText;
            string newGenText  = userText;

            SlyceMergeResult mergeObject = SlyceMerge.Perform3wayDiff(userText, prevGenText, newGenText, out merged);

            Assert.AreEqual(TypeOfDiff.ExactCopy, mergeObject.DiffType, "Mark as Exact Copy.");
            Assert.AreEqual(userText, merged, "The merged text should equal the 3 empty lines.");
        }
Exemplo n.º 3
0
        public void First_line_changed_Go_with_the_User_version()
        {
            string userText     = Helper.GetResource(resourcePrefix + "ThreeLines_FirstLineDeleted.txt");
            string prevGenText  = Helper.GetResource(resourcePrefix + "ThreeLines.txt");
            string newGenText   = Helper.GetResource(resourcePrefix + "ThreeLines_FirstLineChanged.txt");
            string fileExpected = userText;

            SlyceMergeResult mergeObject = SlyceMerge.Perform3wayDiff(userText, prevGenText, newGenText, out merged);

            Assert.AreEqual(TypeOfDiff.Conflict, mergeObject.DiffType, "Cannot merge. Mark as conflicted.");
        }
Exemplo n.º 4
0
        public void Last_line_changed_Cannot_merge_Mark_as_a_conflict()
        {
            string userText     = Helper.GetResource(resourcePrefix + "ThreeLines_LastLineChanged.txt");
            string prevGenText  = Helper.GetResource(resourcePrefix + "ThreeLines.txt");
            string newGenText   = Helper.GetResource(resourcePrefix + "TwoLines.txt");
            string fileExpected = userText;

            SlyceMergeResult mergeObject = SlyceMerge.Perform3wayDiff(userText, prevGenText, newGenText, out merged);

            Assert.AreEqual(TypeOfDiff.Conflict, mergeObject.DiffType, "Cannot merge. Mark as conflicted.");
        }
Exemplo n.º 5
0
        public void Even_when_all_files_are_empty()
        {
            string userText    = string.Empty;
            string prevGenText = userText;
            string newGenText  = userText;

            SlyceMergeResult mergeObject = SlyceMerge.Perform3wayDiff(userText, prevGenText, newGenText, out merged);

            Assert.AreEqual(String.Empty, merged, "The merged text should be empty.");
            Assert.AreEqual(TypeOfDiff.ExactCopy, mergeObject.DiffType, "Mark as Exact Copy.");
        }
Exemplo n.º 6
0
        public void The_merged_file_equals_the_NewGen_TEMPLATECHANGE()
        {
            string userText    = Helper.GetResource(resourcePrefix + "ThreeLines.txt");
            string prevGenText = userText;
            string newGenText  = Helper.GetResource(resourcePrefix + "ThreeOtherLines.txt");

            SlyceMergeResult mergeObject = SlyceMerge.Perform3wayDiff(userText, prevGenText, newGenText, out merged);

            Assert.AreEqual(TypeOfDiff.TemplateChangeOnly, mergeObject.DiffType, "Mark as Exact Copy.");
            Assert.AreEqual(newGenText, merged, "Merged file should equal NewGen.");
        }
Exemplo n.º 7
0
        public void The_merged_file_equals_User_and_NewGen()
        {
            string userText     = Helper.GetResource(resourcePrefix + "TwoLinesWithEmptyLines.txt");
            string prevGenText  = string.Empty;
            string newGenText   = userText;
            string fileExpected = userText;

            SlyceMergeResult mergeObject = SlyceMerge.Perform3wayDiff(userText, prevGenText, newGenText, out merged);

            Assert.AreEqual(TypeOfDiff.ExactCopy, mergeObject.DiffType, "Mark as Exact Copy.");
            Assert.AreEqual(fileExpected, merged, "Merged file should equal User and NewGen.");
        }
Exemplo n.º 8
0
        public void The_merged_equals_the_simple_input_with_linebreaks()
        {
            string userText     = Helper.GetResource(resourcePrefix + "TwoLinesWithEmptyLines.txt");
            string prevGenText  = userText;
            string newGenText   = userText;
            string fileExpected = userText;

            SlyceMergeResult mergeObject = SlyceMerge.Perform3wayDiff(userText, prevGenText, newGenText, out merged);

            Assert.AreEqual(TypeOfDiff.ExactCopy, mergeObject.DiffType, "Mark as Exact Copy.");
            Assert.AreEqual(fileExpected, merged, "The merged text should equal the input.");
        }
Exemplo n.º 9
0
        public void To_NewGen_line1_Include_it()
        {
            string prevGenText  = Helper.GetResource(resourcePrefix + "ThreeLines.txt");
            string userText     = Helper.GetResource(resourcePrefix + "ThreeLines.txt");
            string newGenText   = Helper.GetResource(resourcePrefix + "ThreeLines_LastLineChanged.txt");
            string fileExpected = newGenText;

            SlyceMergeResult mergeObject = SlyceMerge.Perform3wayDiff(userText, prevGenText, newGenText, out merged);

            Assert.AreEqual(TypeOfDiff.TemplateChangeOnly, mergeObject.DiffType, "NewGen change only.");
            Assert.AreEqual(fileExpected, merged, "NewGen change incorporated.");
        }
Exemplo n.º 10
0
        public void User_changes_merge_with_unchanged_NewGen()
        {
            string userText     = Helper.GetResource(resourcePrefix + "ThreeOtherLines.txt");
            string prevGenText  = Helper.GetResource(resourcePrefix + "ThreeLines.txt");
            string newGenText   = Helper.GetResource(resourcePrefix + "ThreeLines.txt");
            string fileExpected = userText;

            SlyceMergeResult mergeObject = SlyceMerge.Perform3wayDiff(userText, prevGenText, newGenText, out merged);

            Assert.AreEqual(TypeOfDiff.UserChangeOnly, mergeObject.DiffType, "User change only.");
            Assert.AreEqual(fileExpected, merged, "NewGen supercedes unchanged user.");
        }
Exemplo n.º 11
0
        public void Last_line_inserted_in_User_Include_it()
        {
            string prevGenText  = Helper.GetResource(resourcePrefix + "TwoLines.txt");
            string userText     = Helper.GetResource(resourcePrefix + "ThreeLines.txt");
            string newGenText   = Helper.GetResource(resourcePrefix + "TwoLines.txt");
            string fileExpected = userText;

            SlyceMergeResult mergeObject = SlyceMerge.Perform3wayDiff(userText, prevGenText, newGenText, out merged);

            Assert.AreEqual(TypeOfDiff.UserChangeOnly, mergeObject.DiffType, "User change only.");
            Assert.AreEqual(fileExpected, merged, "User change incorporated.");
        }
Exemplo n.º 12
0
        public void From_User_remove_from_merge()
        {
            string userText     = Helper.GetResource(resourcePrefix + "ThreeLines_FirstLineDeleted.txt");
            string prevGenText  = Helper.GetResource(resourcePrefix + "ThreeLines.txt");
            string newGenText   = Helper.GetResource(resourcePrefix + "ThreeLines.txt");
            string fileExpected = userText;

            SlyceMergeResult mergeObject = SlyceMerge.Perform3wayDiff(userText, prevGenText, newGenText, out merged);

            Assert.AreEqual(TypeOfDiff.UserChangeOnly, mergeObject.DiffType, "User change only.");
            Assert.AreEqual(fileExpected, merged, "User supercedes unchanged NewGen.");
        }
Exemplo n.º 13
0
        public void The_merged_file_equals_2way_merge_of_User_and_NewGen_CONFLICT()
        {
            string userText     = Helper.GetResource(resourcePrefix + "FourLines.txt");
            string prevGenText  = string.Empty;
            string newGenText   = Helper.GetResource(resourcePrefix + "FourLines_2Different.txt");
            string fileExpected = Helper.GetResource(resourcePrefix + "FourLines_Expected.txt");

            SlyceMergeResult mergeObject = SlyceMerge.Perform3wayDiff(userText, prevGenText, newGenText, out merged);

            Assert.AreEqual(TypeOfDiff.Conflict, mergeObject.DiffType, "Mark as Exact Copy.");
            Assert.AreEqual(fileExpected, merged, "Merged file should equal merge of User and NewGen.");
        }
Exemplo n.º 14
0
        public void Same_first_line_added_to_User_and_NewGen_Include_it()
        {
            string prevGenText  = Helper.GetResource(resourcePrefix + "ThreeLines_FirstLineDeleted.txt");
            string userText     = Helper.GetResource(resourcePrefix + "ThreeLines.txt");
            string newGenText   = Helper.GetResource(resourcePrefix + "ThreeLines.txt");
            string fileExpected = userText;

            SlyceMergeResult mergeObject = SlyceMerge.Perform3wayDiff(userText, prevGenText, newGenText, out merged);

            Assert.AreEqual(TypeOfDiff.ExactCopy, mergeObject.DiffType, "Same changes to both files.");
            Assert.AreEqual(fileExpected, merged, "User change incorporated.");
        }
Exemplo n.º 15
0
        public virtual TypeOfDiff Diff()
        {
            TypeOfDiff diff = TypeOfDiff.ExactCopy;

            DiffTypeExcludingChildren = TypeOfDiff.ExactCopy;

            if (MergedObj != null)
            {
                DiffTypeExcludingChildren = TypeOfDiff.ExactCopy;
            }
            else if (baseConstructs.PrevGen == null)
            {
                if (baseConstructs.NewGen == null && baseConstructs.User == null)
                {
                    DiffTypeExcludingChildren =
                        CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.Warning);
                }
                else if (baseConstructs.NewGen == null)
                {
                    DiffTypeExcludingChildren =
                        CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.UserChangeOnly);
                }
                else if (baseConstructs.User == null)
                {
                    DiffTypeExcludingChildren =
                        CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.TemplateChangeOnly);
                }
                else if (baseConstructs.User.IsTheSame(baseConstructs.NewGen, ComparisonDepth.Outer))
                {
                    DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.ExactCopy);
                }
                else
                {
                    DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.Conflict);
                }

                if (baseConstructs.NewGen != null && baseConstructs.User != null && baseConstructs.GetFirstNonNullObject().IsLeaf)
                {
                    // Do a diff on the body text of our BaseConstructs
                    string userText   = GetFullText(UserObj).TrimStart(Environment.NewLine.ToCharArray());
                    string newgenText = GetFullText(NewGenObj).TrimStart(Environment.NewLine.ToCharArray());

                    TypeOfDiff result = SlyceMerge.PerformTwoWayDiff(userText, newgenText);
                    DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, result);
                }
            }
            else
            {
                if (BaseConstructsAreSame == false)
                {
                    // Do a diff on the outer text of our BaseConstructs
                    string userText    = GetOuterText(UserObj);
                    string newgenText  = GetOuterText(NewGenObj);
                    string prevgenText = GetOuterText(PrevGenObj);
                    string mergedText;

                    DiffTypeExcludingChildren =
                        SlyceMerge.Perform3wayDiff(userText, prevgenText, newgenText, out mergedText, false).DiffType;
                }

                // Also diff ourselves, looking at more than a basic signature comparison but not looking at children (we have already done that above)
                if (baseConstructs.PrevGen == null)
                {
                    if (baseConstructs.NewGen == null)
                    {
                        DiffTypeExcludingChildren =
                            CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.UserChangeOnly);
                    }
                    else if (baseConstructs.User == null && ParentTree.UserCodeRoot != null)
                    // if the user file is null it may not have been generated yet - this is the first run of this project.
                    {
                        DiffTypeExcludingChildren =
                            CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.TemplateChangeOnly);
                    }
                    else
                    {
                        DiffTypeExcludingChildren =
                            CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.UserAndTemplateChange);
                    }
                }
                else
                {
                    if (baseConstructs.PrevGen.IsTheSame(baseConstructs.NewGen, ComparisonDepth.Outer) == false)
                    {
                        // If NewGen is null, this will return false.
                        DiffTypeExcludingChildren =
                            CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.TemplateChangeOnly);
                    }
                    if (baseConstructs.PrevGen.IsTheSame(baseConstructs.User, ComparisonDepth.Outer) == false)
                    {
                        // If User is null, this will return false.
                        DiffTypeExcludingChildren =
                            CombineChildDiffTypes(diffTypeExcChildren, TypeOfDiff.UserChangeOnly);
                    }
                    if (baseConstructs.NewGen != null && baseConstructs.User != null &&
                        diffTypeExcChildren == TypeOfDiff.Conflict &&
                        baseConstructs.NewGen.IsTheSame(baseConstructs.User, ComparisonDepth.Outer))
                    {
                        DiffTypeExcludingChildren = TypeOfDiff.UserAndTemplateChange;
                    }
                    if (baseConstructs.NewGen == null && baseConstructs.User == null)
                    {
                        DiffTypeExcludingChildren = TypeOfDiff.UserAndTemplateChange;
                    }
                }

                if (baseConstructs.GetFirstNonNullObject().IsLeaf)
                {
                    // Do a diff on the body text of our BaseConstructs
                    string userText    = GetBodyText(UserObj).TrimStart(Environment.NewLine.ToCharArray());
                    string newgenText  = GetBodyText(NewGenObj).TrimStart(Environment.NewLine.ToCharArray());
                    string prevgenText = GetBodyText(PrevGenObj).TrimStart(Environment.NewLine.ToCharArray());
                    string mergedText;

                    TypeOfDiff result = SlyceMerge.Perform3wayDiff(userText, prevgenText, newgenText, out mergedText).DiffType;
                    DiffTypeExcludingChildren = CombineChildDiffTypes(diffTypeExcChildren, result);
                }

                if (baseConstructs.NewGen != null && ParentTree.PrevGenCodeRoot == null && ParentTree.UserCodeRoot == null)
                {
                    // Template base construct exists, but Prevgen and User CodeRoots haven't been added.. Make it an exact copy.
                    DiffTypeExcludingChildren = TypeOfDiff.ExactCopy;
                }
            }

            // Diff out child nodes.
            foreach (CodeRootMapNode node in children)
            {
                diff = CombineChildDiffTypes(diff, node.Diff());
            }

            diff = CombineChildDiffTypes(diff, diffTypeExcChildren);

            return(diff);
        }
Exemplo n.º 16
0
        /// <summary>
        /// Performs the diff between the 3 files, even if some of them do not exist.
        /// </summary>
        protected override bool PerformDiffInternal()
        {
            //////////////////////////
            MergedFile = NewGenFile;

            if (!UserFile.IsFileOnDisk)
            {
                CurrentDiffResult.DiffType = TypeOfDiff.NewFile;
            }
            else if (UserFile.HexStringMD5() == NewGenFile.HexStringMD5())
            {
                CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
            }
            else
            {
                CurrentDiffResult.DiffType = TypeOfDiff.TemplateChangeOnly;
            }

            return(true);

            ///////////////////////////
            if (IntelliMerge == IntelliMergeType.Overwrite)
            {
                CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
                MergedFile = NewGenFile;
                return(true);
            }

            if (IntelliMerge == IntelliMergeType.CreateOnly)
            {
                CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
                MergedFile = UserFile.HasContents ? UserFile : NewGenFile;

                return(true);
            }

            if (UserFile.HasContents == false && PrevGenFile.HasContents == false && NewGenFile.HasContents == false)
            {
                throw new InvalidOperationException("Cannot perform a diff if there are no files!");
            }

            if (MergedFileExists)
            {
                CurrentDiffResult.DiffPerformedSuccessfully = true;
                CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
                CurrentDiffResult.DiffWarningDescription = CurrentDiffResult.ParserWarningDescription = "";

                return(true);
            }

            if (PrevGenFile.HasContents &&
                UserFile.HasContents &&
                NewGenFile.HasContents)
            {
                // Perform 3-way diff
                string fileBodyParent = PrevGenFile.GetContents();
                string fileBodyUser   = UserFile.GetContents();
                // Template code is not formatted until it is needed. Do the formatting here.

                string           fileBodyGenerated;
                string           mergedText;
                SlyceMergeResult slyceMerge;
                if (IntelliMerge == IntelliMergeType.CSharp)
                {
                    if (NewGenFile.GetContents().Trim() == string.Empty)
                    {
                        fileBodyGenerated = "";
                    }
                    else
                    {
                        CSharpParser formatter = new CSharpParser();
                        formatter.ParseCode(NewGenFile.FilePath, NewGenFile.GetContents());
                        if (formatter.ErrorOccurred)
                        {
                            CurrentDiffResult.ParserWarningDescription = formatter.GetFormattedErrors();
                            return(false);
                        }
                        CodeRoot codeRoot = (CodeRoot)formatter.CreatedCodeRoot;
                        fileBodyGenerated = codeRoot.ToString();
                    }
                    slyceMerge = SlyceMerge.Perform3wayDiff(fileBodyUser, fileBodyParent, fileBodyGenerated, out mergedText, false);
                }
                else
                {
                    fileBodyGenerated = NewGenFile.GetContents();
                    slyceMerge        = SlyceMerge.Perform3wayDiff(fileBodyUser, fileBodyParent, fileBodyGenerated, out mergedText, true);
                    MergedFile        = new TextFile(mergedText);
                }
                CurrentDiffResult.DiffType = slyceMerge.DiffType;

                if (slyceMerge.DiffType == TypeOfDiff.Warning)
                {
                    // TODO: What should be done here?
                    throw new Exception(
                              "There was a warning during the diff process when there shouldn't have been. Please report this to Slyce.");
                }

                if (slyceMerge.DiffType != TypeOfDiff.ExactCopy)
                {
                    return(PerformSuperDiff());
                }

                // File was exact copy - use user version
                MergedFile = new TextFile(fileBodyUser);
            }
            else if (PrevGenFile.HasContents &&
                     UserFile.HasContents == false &&
                     NewGenFile.HasContents)
            {
                // No user file, just use the template file
                CurrentDiffResult.DiffType = TypeOfDiff.Warning;
                CurrentDiffResult.DiffWarningDescription =
                    "The User's version of this file has been deleted or renamed, but the Template and previous version of this file still exist.";
                MergedFile = new TextFile(NewGenFile.GetContents());
            }
            else if (PrevGenFile.HasContents == false &&
                     UserFile.HasContents &&
                     NewGenFile.HasContents)
            {
                //CurrentDiffResult.DiffType = TypeOfDiff.Warning;
                //CurrentDiffResult.DiffWarningDescription =
                //    "User version of a file clashes with a new file the template is trying to create.";

                // Perform 2-way diff
                string fileBodyNewGen = NewGenFile.GetContents();
                string fileBodyUser   = UserFile.GetContents();
                CurrentDiffResult.DiffType = SlyceMerge.PerformTwoWayDiff(fileBodyNewGen, fileBodyUser);

                if (CurrentDiffResult.DiffType != TypeOfDiff.ExactCopy)
                {
                    // Also perform a super diff
                    return(PerformSuperDiff());
                }
                MergedFile = new TextFile(fileBodyUser);
            }
            else if (PrevGenFile.HasContents == false &&
                     UserFile.HasContents == false &&
                     NewGenFile.HasContents)
            {
                // The template has added a new file.
                CurrentDiffResult.DiffType = TypeOfDiff.ExactCopy;
                MergedFile = new TextFile(NewGenFile.GetContents());
            }
            else
            {
                // Cases covered by this else:
                // * User and prevgen file exist, no template
                // * Prevgen, no user or template.
                // * User file, no template or prevgen
                // TODO: Shouldn't really be a warning...
                CurrentDiffResult.DiffType = TypeOfDiff.Warning;
                throw new Exception(string.Format("TODO: determine course of action, what should be copied to staging folder, because no file exists: \nparent file path:\"{0}\" : {1}\nuser file path:\"{2}\" : {3}\ntemplate file path:\"{4}\" : {5}", PrevGenFile.FilePath, PrevGenFile.HasContents, UserFile.FilePath, UserFile.HasContents, NewGenFile.FilePath, NewGenFile.HasContents));
            }

            return(true);
        }
Exemplo n.º 17
0
        /// <summary>
        /// Returns a IBaseConstruct which is the result of merging the BaseConstructs in this subtree.
        /// </summary>
        /// <returns>A IBaseConstruct which is the result of merging the BaseConstructs in this subtree.</returns>
        /// <exception cref="InvalidOperationException">Thrown if there are no BaseConstructs in this node
        /// or any of its children.</exception>
        public virtual IBaseConstruct GetMergedBaseConstruct()
        {
            if (mergedObj != null)
            {
                return(mergedObj);
            }

            IBaseConstruct newBc = baseConstructs.GetFirstNonNullObject();

            if (newBc == null)
            {
                throw new InvalidOperationException(
                          "Cannot create a merged IBaseConstruct because this node contains no data");
            }

            newBc = newBc.Clone();

            if (baseConstructs.DetermineMissingConstructs() == MissingObject.None)
            {
                bool result = newBc.CustomMergeStep(baseConstructs.User, baseConstructs.NewGen, baseConstructs.PrevGen);
                if (result == false)
                {
                    // Need to notify the user of this issue.
                    throw new MergeException("Could not perform automatic merge, CustomMergeStep failed. ", GetFirstValidBaseConstruct().FullyQualifiedIdentifer, GetFirstValidBaseConstruct().GetType().ToString());
                }
            }

            if (newBc is IBody)
            {
                IBody  bodyNode    = (IBody)newBc;
                string userText    = GetBodyText(UserObj);
                string newgenText  = GetBodyText(NewGenObj);
                string prevgenText = GetBodyText(PrevGenObj);

                if (UserObj == null && NewGenObj != null)
                {
                    bodyNode.BodyText = newgenText;
                }
                else if (NewGenObj == null && UserObj != null)
                {
                    bodyNode.BodyText = userText;
                }
                else
                {
                    string     mergedText;
                    TypeOfDiff result = SlyceMerge.Perform3wayDiff(userText, prevgenText, newgenText, out mergedText).DiffType;
                    if (result == TypeOfDiff.Conflict)
                    {
                        throw new InvalidOperationException("Cannot merge BaseConstructs if there is a conflict in their body text.");
                    }
                    bodyNode.BodyText = mergedText;
                }
            }

            foreach (CodeRootMapNode child in children)
            {
                MissingObject missingObjects = child.DetermineMissingConstructs();
                if ((missingObjects & MissingObject.NewGen) != 0 &&
                    (missingObjects & MissingObject.User) != 0)
                {
                    continue;
                }

                IBaseConstruct childBC = child.GetMergedBaseConstruct();
                newBc.AddChild(childBC);
            }

            return(newBc);
        }
Exemplo n.º 18
0
        internal void PerformDiffOfFile(DiffFile diffFile, ref bool fileNeedsToBeCounted)
        {
            // Don't process files that had errors during generation
            for (int errFileCounter = 0; errFileCounter < GenerationErrors.Count; errFileCounter++)
            {
                if (Slyce.Common.Utility.StringsAreEqual(diffFile.RelativePath, GenerationErrors[errFileCounter].FileName, false))
                {
                    //continue;
                    return;
                }
            }
            if (UniqueFilesForCount[diffFile.RelativePath] != null &&
                (bool)UniqueFilesForCount[diffFile.RelativePath] == false)
            {
                fileNeedsToBeCounted = true;
                UniqueFilesForCount[diffFile.RelativePath] = true;
            }
            else
            {
                fileNeedsToBeCounted = false;
            }
            if (diffFile.Path.IndexOf(".aaz") > 0 ||
                diffFile.HasParseError)
            {
                //continue;
                return;
            }
            if (FileBeingProcessed != null)
            {
                FileBeingProcessed(diffFile.Path);
            }
            // Perform a 3-way diff on the file
            string parentFile   = Path.Combine(PreviousGenerationFolder, diffFile.RelativePath);
            string userFile     = Path.Combine(Controller.Instance.ProjectSettings.ProjectPath, diffFile.RelativePath);
            string templateFile = Path.Combine(Controller.Instance.GetTempFilePathForComponent(ComponentKey.WorkbenchFileGenerator), diffFile.RelativePath);
            string mergedFile   = Path.Combine(StagingFolder, diffFile.RelativePath + ".merged");

            if (CheckFilesForModifications(diffFile.RelativePath) == false)
            {
                RaiseDiffFinishedEvent(diffFile.Name, TypeOfDiff.ExactCopy);
                return;
            }

            diffFile.FilePathTemplate = templateFile;
            diffFile.FilePathUser     = userFile;
            diffFile.FilePathPrevGen  = parentFile;

            if (File.Exists(mergedFile))
            {
                bool mergeComplete = true;

                // Binary files are never in an unknown state, they are all or nothing.
                // Text files need to be checked.
                if (diffFile.IsText)
                {
                    using (TextReader tr = new StreamReader(mergedFile))
                    {
                        string line;
                        //int lineCounter = 0;

                        while ((line = tr.ReadLine()) != null &&
                               mergeComplete)
                        {
                            int pipeIndex = line.IndexOf("|");
                            int backColor = int.Parse(line.Substring(0, pipeIndex));

                            if (backColor != -1 &&
                                backColor != 0)
                            {
                                mergeComplete = false;
                            }
                            //lineCounter++;
                        }
                    }
                }
                if (mergeComplete)
                {
                    diffFile.DiffType = TypeOfDiff.Warning;
                }
                else
                {
                    diffFile.DiffType = TypeOfDiff.Conflict;
                }
            }
            else
            {
                if (diffFile.IsText)
                {
                    if (File.Exists(parentFile) &&
                        File.Exists(userFile) &&
                        File.Exists(templateFile))
                    {
                        // Perform 3-way diff
                        string fileBodyParent    = IOUtility.GetTextFileBody(parentFile);
                        string fileBodyUser      = IOUtility.GetTextFileBody(userFile);
                        string fileBodyGenerated = IOUtility.GetTextFileBody(templateFile);

                        string mergedText;
                        slyceMerge        = SlyceMerge.Perform3wayDiff(fileBodyUser, fileBodyParent, fileBodyGenerated, out mergedText);
                        diffFile.DiffType = slyceMerge.DiffType;
                        string newFile = "";

                        if (slyceMerge.DiffType != TypeOfDiff.Conflict)
                        {
                            switch (slyceMerge.DiffType)
                            {
                            case TypeOfDiff.ExactCopy:
                                newFile = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                                Slyce.Common.Utility.FileCopy(userFile, newFile);
                                break;

                            case TypeOfDiff.TemplateChangeOnly:
                                newFile = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                                Slyce.Common.Utility.FileCopy(templateFile, newFile);
                                break;

                            case TypeOfDiff.UserAndTemplateChange:
                                newFile = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";

                                if (!Directory.Exists(Path.GetDirectoryName(newFile)))
                                {
                                    Directory.CreateDirectory(Path.GetDirectoryName(newFile));
                                }
                                Slyce.Common.Utility.WriteToFile(newFile, mergedText);
                                break;

                            case TypeOfDiff.UserChangeOnly:
                                newFile = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                                Slyce.Common.Utility.FileCopy(userFile, newFile);
                                break;

                            case TypeOfDiff.Warning:
                                throw new Exception("Oops");
                            }
                        }
                    }
                    else if (File.Exists(parentFile) &&
                             File.Exists(userFile) &&
                             !File.Exists(templateFile))
                    {
                        // No template file, just use the user file
                        diffFile.DiffType = TypeOfDiff.UserChangeOnly;
                        string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                        Slyce.Common.Utility.FileCopy(userFile, newPath);
                    }
                    else if (File.Exists(parentFile) &&
                             !File.Exists(userFile) &&
                             File.Exists(templateFile))
                    {
                        // No user file, just use the template file
                        diffFile.DiffType = TypeOfDiff.TemplateChangeOnly;
                        string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                        Slyce.Common.Utility.FileCopy(templateFile, newPath);
                    }
                    else if (!File.Exists(parentFile) &&
                             File.Exists(userFile) &&
                             File.Exists(templateFile))
                    {
                        // No parent file, make sure the user merges the template and user files
                        SlyceMerge.LineSpan[] userLines;
                        SlyceMerge.LineSpan[] templateLines;
                        string combinedText;
                        diffFile.DiffType = SlyceMerge.PerformTwoWayDiff(false, IOUtility.GetTextFileBody(userFile), IOUtility.GetTextFileBody(templateFile), out userLines, out templateLines, out combinedText);

                        if (diffFile.DiffType == TypeOfDiff.ExactCopy)
                        {
                            string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                            Slyce.Common.Utility.FileCopy(templateFile, newPath);
                        }
                        else
                        {
                            throw new NotImplementedException("This scenario has not been handled yet. Please contact [email protected] with: PerformDiffOfFolder(PrevGen file doesn't exist, and TypeOfDiff = " + diffFile.DiffType + ")");
                        }
                        //diffFile.DiffType = SlyceMerge.TypeOfDiff.Conflict; // TODO: Work out what should be done in this instance
                        //throw new Exception("TODO: determine course of action, what should be copied to staging folder.");
                        //string newPath = templateFile.Replace(ProjectFolder, StagingFolder) + ".copy";
                        //Utility.FileCopy(templateFile, newPath);
                    }
                    else if (File.Exists(parentFile) &&
                             !File.Exists(userFile) &&
                             !File.Exists(templateFile))
                    {
                        // TODO: It looks like the file was deleted by the user, AND it was removed from the template, so therefore the
                        // user doesn't want this file anymore. Get user to confirm?
                        string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                        Slyce.Common.Utility.FileCopy(parentFile, newPath);
                    }
                    else if (!File.Exists(parentFile) &&
                             !File.Exists(userFile) &&
                             File.Exists(templateFile))
                    {
                        string newPath = templateFile.Replace(Controller.Instance.GetTempFilePathForComponent(ComponentKey.WorkbenchFileGenerator), StagingFolder) + ".copy";
                        Slyce.Common.Utility.FileCopy(templateFile, newPath);
                    }
                    else if (!File.Exists(parentFile) &&
                             File.Exists(userFile) &&
                             !File.Exists(templateFile))
                    {
                        // TODO: Do we really need to go to the effort of copying etc, because it only exists in the user folder,
                        // so if we take no action it will still exist there - that should be fine ;-)
                        string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                        Slyce.Common.Utility.FileCopy(userFile, newPath);
                    }
                    else
                    {
                        // TODO: Shouldn't really be a warning...
                        diffFile.DiffType = TypeOfDiff.Warning;
                        throw new Exception(string.Format("TODO: determine course of action, what should be copied to staging folder, because no file exists: \n{0}\n{1}\n{2}", parentFile, userFile, templateFile));
                    }
                }
                else                 // Binary file
                {
                    string crcParent   = File.Exists(parentFile) ? Slyce.Common.Utility.GetCheckSumOfFile(parentFile) : "";
                    string crcTemplate = File.Exists(templateFile) ? Slyce.Common.Utility.GetCheckSumOfFile(templateFile) : "";
                    string crcUser     = File.Exists(userFile) ? Slyce.Common.Utility.GetCheckSumOfFile(userFile) : "";

                    diffFile.MD5Parent   = crcParent;
                    diffFile.MD5Template = crcTemplate;
                    diffFile.MD5User     = crcUser;

                    // TODO: perform CheckSum of binary file
                    if (!string.IsNullOrEmpty(crcParent) &&
                        !string.IsNullOrEmpty(crcTemplate) &&
                        !string.IsNullOrEmpty(crcUser))
                    {
                        if (crcParent == crcUser &&
                            crcUser == crcTemplate)
                        {
                            diffFile.DiffType = TypeOfDiff.ExactCopy;
                            string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                            Slyce.Common.Utility.FileCopy(userFile, newPath);
                        }
                        else if (crcParent == crcUser &&
                                 crcParent != crcTemplate)
                        {
                            diffFile.DiffType = TypeOfDiff.TemplateChangeOnly;
                            string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                            Slyce.Common.Utility.FileCopy(userFile, newPath);
                        }
                        else if (crcParent != crcUser &&
                                 crcParent == crcTemplate)
                        {
                            diffFile.DiffType = TypeOfDiff.UserChangeOnly;
                            string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                            Slyce.Common.Utility.FileCopy(userFile, newPath);
                        }
                        else if (crcParent != crcUser &&
                                 crcUser == crcTemplate)
                        {
                            diffFile.DiffType = TypeOfDiff.UserAndTemplateChange;
                        }
                    }
                    else if (string.IsNullOrEmpty(crcParent) &&
                             !string.IsNullOrEmpty(crcTemplate) &&
                             !string.IsNullOrEmpty(crcUser))
                    {
                        diffFile.DiffType = TypeOfDiff.Conflict;
                    }
                    else if (!string.IsNullOrEmpty(crcParent) &&
                             !string.IsNullOrEmpty(crcTemplate) &&
                             string.IsNullOrEmpty(crcUser))
                    {
                        diffFile.DiffType = TypeOfDiff.TemplateChangeOnly;
                        string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                        Slyce.Common.Utility.FileCopy(templateFile, newPath);
                    }
                    else if (!string.IsNullOrEmpty(crcParent) &&
                             string.IsNullOrEmpty(crcTemplate) &&
                             !string.IsNullOrEmpty(crcUser))
                    {
                        diffFile.DiffType = TypeOfDiff.UserChangeOnly;
                        string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                        Slyce.Common.Utility.FileCopy(userFile, newPath);
                    }
                    else if (string.IsNullOrEmpty(crcParent) &&
                             !string.IsNullOrEmpty(crcTemplate) &&
                             string.IsNullOrEmpty(crcUser))
                    {
                        // This is a new file that has been generated
                        diffFile.DiffType = TypeOfDiff.ExactCopy;
                        string newPath = Path.Combine(StagingFolder, diffFile.RelativePath) + ".copy";
                        Slyce.Common.Utility.FileCopy(templateFile, newPath);
                    }
                    else
                    {
                        throw new NotImplementedException("Not coded yet. Seems like only one version of binary file exists. Probably just need to copy as-is.");
                    }
                }
            }
            if (diffFile.DiffType != TypeOfDiff.ExactCopy)
            {
                // Only perform the costly SuperDiff if it is not an exact copy
                //ArchAngel.IntelliMerge.DiffItems.DiffFile diffFile = diffFile;
                PerformSuperDiff(ref diffFile);
            }
            if (fileNeedsToBeCounted)
            {
                switch (diffFile.DiffType)
                {
                case TypeOfDiff.Conflict:
                    m_numConflicts++;
                    break;

                case TypeOfDiff.ExactCopy:
                    m_numExactCopy++;
                    break;

                case TypeOfDiff.TemplateChangeOnly:
                case TypeOfDiff.UserAndTemplateChange:
                case TypeOfDiff.UserChangeOnly:
                case TypeOfDiff.Warning:
                    m_numResolvable++;
                    break;

                default:
                    throw new NotImplementedException("Not coded yet");
                }
                RaiseDiffFinishedEvent(diffFile.Name, diffFile.DiffType);
            }

            Slyce.Common.Utility.DeleteFileBrute(templateFile + ".prevgen.md5");
            Slyce.Common.Utility.DeleteFileBrute(templateFile + ".user.md5");

            if (diffFile.DiffType == TypeOfDiff.ExactCopy)
            {
                // Store the MD5 hashes of the files we just diff'd, so we don't do them again.
                if (File.Exists(parentFile))
                {
                    Slyce.Common.Utility.CreateMD5HashFileForTextFile(parentFile, templateFile + ".prevgen.md5");
                }
                if (File.Exists(userFile))
                {
                    Slyce.Common.Utility.CreateMD5HashFileForTextFile(userFile, templateFile + ".user.md5");
                }
            }
        }