コード例 #1
0
        public static int Main(string[] args)
        {
            try
            {
                string ourFilePath;
                string commonFilePath;
                string theirFilePath;

                if (Platform.IsMono)
                {
                    ourFilePath    = args[0];
                    commonFilePath = args[1];
                    theirFilePath  = args[2];
                }
                else
                {
                    // Convert the input arguments from cp1252 -> utf8 -> ucs2
                    // It always seems to be 1252, even when the input code page is actually something else. CP 2012-03
                    // var inputEncoding = Console.InputEncoding;
                    var inputEncoding = Encoding.GetEncoding(1252);
                    ourFilePath    = Encoding.UTF8.GetString(inputEncoding.GetBytes(args[0]));
                    commonFilePath = Encoding.UTF8.GetString(inputEncoding.GetBytes(args[1]));
                    theirFilePath  = Encoding.UTF8.GetString(inputEncoding.GetBytes(args[2]));
                    Console.WriteLine("ChorusMerge: Input encoding {0}",
                                      inputEncoding.EncodingName);
                }

                //this was originally put here to test if console writes were making it out to the linux log or not
                Console.WriteLine("ChorusMerge: {0}, {1}, {2}", ourFilePath, commonFilePath, theirFilePath);

#if RUNINDEBUGGER
                var order = new MergeOrder(ourFilePath, commonFilePath, theirFilePath, new MergeSituation(ourFilePath, "Me", "CHANGETHIS", "YOU", "CHANGETHIS", MergeOrder.ConflictHandlingModeChoices.WeWin));
#else
                MergeOrder order = MergeOrder.CreateUsingEnvironmentVariables(ourFilePath, commonFilePath, theirFilePath);
#endif
                var handlers = ChorusFileTypeHandlerCollection.CreateWithInstalledHandlers();
                var handler  = handlers.GetHandlerForMerging(order.pathToOurs);

                //DispatchingMergeEventListener listenerDispatcher = new DispatchingMergeEventListener();
                //using (HumanLogMergeEventListener humanListener = new HumanLogMergeEventListener(order.pathToOurs + ".ChorusNotes.txt"))
                using (var xmlListener = new ChorusNotesMergeEventListener(order.pathToOurs + ".NewChorusNotes"))
                {
//                    listenerDispatcher.AddEventListener(humanListener);
//                    listenerDispatcher.AddEventListener(xmlListener);
                    order.EventListener = xmlListener;

                    handler.Do3WayMerge(order);
                }
            }
            catch (Exception e)
            {
                ErrorWriter.WriteLine("ChorusMerge Error: " + e.Message);
                ErrorWriter.WriteLine(e.StackTrace);
                return(1);
            }
            return(0);           //no error
        }
コード例 #2
0
        public void FileDidNotExist_NoConflicts_DoesNotCreatesEmptyNotesFile()
        {
            var tempFile = Path.GetTempFileName();

            File.Delete(tempFile);
            using (ChorusNotesMergeEventListener log = new ChorusNotesMergeEventListener(tempFile))
            {
            }
            Assert.IsFalse(File.Exists(tempFile));
        }
コード例 #3
0
        public void AssertSingleConflictType <TConflict>()
        {
            string cmlFile = ChorusNotesMergeEventListener.GetChorusNotesFilePath(UserFile.Path);

            Assert.IsTrue(File.Exists(cmlFile), "ChorusNotes file should have been in working set");
            Assert.IsTrue(Synchronizer.Repository.GetFileIsInRepositoryFromFullPath(cmlFile), "ChorusNotes file should have been in repository");

            XmlDocument doc = new XmlDocument();

            doc.Load(cmlFile);
            Assert.AreEqual(1, doc.SafeSelectNodes("notes/annotation").Count);
        }
コード例 #4
0
 public void FileDidNotExist_CreatesCorrectFile()
 {
     using (TempFile logFile = TempFile.CreateAndGetPathButDontMakeTheFile())
     {
         using (ChorusNotesMergeEventListener log = new ChorusNotesMergeEventListener(logFile.Path))
         {
             log.ConflictOccurred(new DummyConflict());
             log.ConflictOccurred(new DummyConflict());
         }
         XmlDocument doc = new XmlDocument();
         doc.Load(logFile.Path);
         Assert.AreEqual(2, doc.SelectNodes("notes/annotation").Count);
     }
 }
コード例 #5
0
        /// <summary>
        /// The only entry point in the class. This method (plus its private methods) does the work of the class.
        /// </summary>
        /// <param name="pathname">Pathname of the split up file that contains <paramref name="element"/>.</param>
        /// <param name="sortedData">All of the data being collected that will end up as CmObject elments in the rebuilt fwdata file. These are sorted by guid order.</param>
        /// <param name="element">The xml element to check for a duplicate guid.</param>
        /// <param name="isOwnSeqNode">Out paramenter that is used by caller.</param>
        /// <param name="className">The class of <paramref name="element"/>.</param>
        /// <returns></returns>
        internal static string CheckForDuplicateGuid(string pathname, SortedDictionary <string, XElement> sortedData, XElement element, out bool isOwnSeqNode, out string className)
        {
            var          mdc = MetadataCache.MdCache;
            FdoClassInfo classInfo;

            isOwnSeqNode = GetClassInfoFromElement(mdc, element, out classInfo, out className);
            var elementGuid = element.Attribute(SharedConstants.GuidStr).Value.ToLowerInvariant();

            if (!sortedData.ContainsKey(elementGuid))
            {
                return(elementGuid);
            }

            // Does LT-12524 "Handle merge in case of conflicting move object to different destination".
            // This need will manifest itself in the guid already being in 'sortedData' and an exception being thrown.
            // At this point element has not been flattened, so stuff it owns will still be in it.
            // That is good, if we go with JohnT's idea of using a new guid for guids that are already in 'sortedData'.
            // By changing it before flattening, then the owned stuff will get the new one for their ownerguid attrs.
            // The owned stuff will also be dup, so the idea is to also change their guids right now. [ChangeGuids is recursive down the owning tree.]
            // Just be sure to change 'elementGuid' to the new one. :-)
            // The first item added to sortedData has been flattened by this point, but not any following ones.
            var oldGuid = elementGuid;

            elementGuid = ChangeGuids(mdc, classInfo, element);
            using (var listener = new ChorusNotesMergeEventListener(ChorusNotesMergeEventListener.GetChorusNotesFilePath(pathname)))
            {
                // Don't try to use something like this:
                // var contextGenerator = new FieldWorkObjectContextGenerator();
                // contextGenerator.GenerateContextDescriptor(element.ToString(), pathname)
                // it will fail for elements in an owning sequence because in the unflattened form
                // the object representing a sequence item has element name <ownseq> which won't generate a useful label.
                var context = FieldWorksMergeServices.GenerateContextDescriptor(pathname, elementGuid, className);
                listener.EnteringContext(context);
                // Adding the conflict to the listener, will result in the ChorusNotes file being updated (created if need be.)
                var conflict = new IncompatibleMoveConflict(className, CmObjectFlatteningService.GetXmlNode(element))
                {
                    Situation = new NullMergeSituation()
                };
                // The order of the next three lines is critical. Each prepares state that the following lines use.
                listener.RecordContextInConflict(conflict);
                conflict.HtmlDetails = MakeHtmlForIncompatibleMove(conflict, oldGuid, elementGuid, element);
                listener.ConflictOccurred(conflict);
                File.WriteAllText(pathname + "." + SharedConstants.dupid, "");
            }
            return(elementGuid);
        }
コード例 #6
0
        public void ConflictFileIsCheckedIn()
        {
            using (RepositoryWithFilesSetup bob = RepositoryWithFilesSetup.CreateWithLiftFile("bob"))
            {
                using (RepositoryWithFilesSetup sally = RepositoryWithFilesSetup.CreateByCloning("sally", bob))
                {
                    bob.ReplaceSomething("bob");
                    bob.AddAndCheckIn();
                    sally.ReplaceSomething("sally");
                    sally.CheckinAndPullAndMerge(bob);

                    string notesFile = ChorusNotesMergeEventListener.GetChorusNotesFilePath(sally.UserFile.Path);
                    Console.WriteLine("notesFile '{0}'", notesFile);
                    Assert.That(notesFile, Does.Exist, "Conflict file should have been in working set");
                    Assert.That(sally.Synchronizer.Repository.GetFileIsInRepositoryFromFullPath(notesFile), Is.True, "Notes file should have been added to repository");
                }
            }
        }
コード例 #7
0
        public void FileOutput_WithContent_UsesCanonicalXmlSettings()
        {
            string expected = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n"
                              + "<notes\r\n"
                              + "\tversion=\"0\">\r\n"
                              + "\t<annotation>Dummy</annotation>\r\n"
                              + "</notes>";

            using (var logFile = TempFile.CreateAndGetPathButDontMakeTheFile())
            {
                using (var log = new ChorusNotesMergeEventListener(logFile.Path))
                {
                    log.ConflictOccurred(new DummyConflict());
                }
                string result = File.ReadAllText(logFile.Path);
                Assert.AreEqual(expected, result);
            }
        }
コード例 #8
0
        /// <summary>
        /// This method will detect changed vs deleted file conflicts in the output coming from mercurial.
        /// It produces a conflict for that situation and tells mercurial to keep the changed file.
        /// <note>The default response for mercurial is to keep the changed, but on some user systems (Windows 8?)
        /// mercurial will pause waiting for input instead of using the default answer.</note>
        /// </summary>
        private bool HandleChangedVsDeletedFiles(string line, StreamWriter standardInput)
        {
            // The two situations we are dealing with are:
            //
            // local changed [filename] which remote deleted
            // use (c)hanged version or (d)elete?
            //		and
            // remote changed [filename] which local deleted
            // use (c)hanged version or leave (d)eleted?

            string changedVsDeletedFile = null;
            var    match = Regex.Match(line, @"local changed (.*) which remote deleted");

            if (match.Captures.Count > 0)
            {
                changedVsDeletedFile = match.Groups[1].Value;
            }
            else
            {
                match = Regex.Match(line, @"remote changed (.*) which local deleted");
                if (match.Captures.Count > 0)
                {
                    changedVsDeletedFile = match.Groups[1].Value;
                }
            }
            if (changedVsDeletedFile != null)
            {
                var conflictPath   = Path.Combine(_rootDirectory, changedVsDeletedFile);
                var conflictReport = new FileChangedVsFileDeletedConflict(conflictPath);
                using (var chorusNoteCreator = new ChorusNotesMergeEventListener(ChorusNotesMergeEventListener.GetChorusNotesFilePath(conflictPath)))
                {
                    chorusNoteCreator.ConflictOccurred(conflictReport);
                }
                return(true);
            }
            // Send hg the response it might be waiting for:
            if (line.Contains(@"(c)hanged") && line.Contains(@"(d)elete"))
            {
                standardInput.WriteLine('c');
                return(true);
            }
            // This input line was not related to a Changed vs Deleted File situation
            return(false);
        }
コード例 #9
0
        public void EnsureMergedCData_IsRetained()
        {
            using (var common = TempFile.WithFilename("common.ChorusNotes"))
                using (var ours = TempFile.WithFilename("ours.ChorusNotes"))
                    using (var theirs = TempFile.WithFilename("theirs.ChorusNotes"))
                    {
                        const string commonData =
                            @"<?xml version='1.0' encoding='utf-8'?>
<notes
	version='0'>
	<annotation
		class='mergeConflict'
		ref='silfw://localhost/link?app=flex&amp;database=current&amp;server=&amp;tool=default&amp;guid=bab7776e-531b-4ce1-997f-fa638c09e381&amp;tag=&amp;label=Entry &quot;pintu&quot;'
		guid='1cb66d60-90d5-4367-95b1-b7b41eb8986d'>
		<message
			author='merger'
			status='open'
			guid='ef89b532-5441-48a8-aea9-065b6ab5cfbd'
			date='2012-07-20T14:18:35Z'>Entry 'pintu': user57@tpad2 deleted this element, while user57 edited it. The automated merger kept the change made by user57.<![CDATA[<conflict
	typeGuid='3d9ba4ac-4a25-11df-9879-0800200c9a66'
	class='Chorus.merge.xml.generic.EditedVsRemovedElementConflict'
	relativeFilePath='Linguistics\Lexicon\Lexicon.lexdb'
	type='Removed Vs Edited Element Conflict'
	guid='ef89b532-5441-48a8-aea9-065b6ab5cfbd'
	date='2012-07-20T14:18:35Z'
	whoWon='user57'
	htmlDetails='&lt;head&gt;&lt;style type='text/css'&gt;&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;div class='description'&gt;Entry &quot;pintu&quot;: user57@tpad2 deleted this element, while user57 edited it. The automated merger kept the change made by user57.&lt;/div&gt;&lt;div class='alternative'&gt;user57's changes: &amp;lt;LexEntry guid=&quot;bab7776e-531b-4ce1-997f-fa638c09e381&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DateCreated val=&quot;2012-7-20 13:46:3.625&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DateModified val=&quot;2012-7-20 &lt;span style=&quot;text-decoration: line-through; color: red&quot;&gt;13:46:3.625&lt;/span&gt;&lt;span style=&quot;background: Yellow&quot;&gt;14:14:20.218&lt;/span&gt;&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DoNotUseForParsing val=&quot;False&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;HomographNumber val=&quot;0&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;LexemeForm&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MoStemAllomorph guid=&quot;556f6e08-0fb2-4171-82e0-6dcdddf9490b&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Form&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;AUni ws=&quot;id&quot;&gt;pintu&amp;lt;/AUni&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/Form&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;IsAbstract val=&quot;False&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MorphType&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;objsur guid=&quot;d7f713e8-e8cf-11d3-9764-00c04f186933&quot; t=&quot;r&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphType&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MoStemAllomorph&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/LexemeForm&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;MorphoSyntaxAnalyses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MoStemMsa guid=&quot;f63e03f0-ac9d-4b1b-980f-316bbb741f70&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphoSyntaxAnalyses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;Senses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ownseq class=&quot;LexSense&quot; guid=&quot;dad069de-dfad-45f6-a5d2-449265adbc3a&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;Definition&gt;&lt;/span&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;AStr&lt;/span&gt; &lt;span style=&quot;background: Yellow&quot;&gt;ws=&quot;en&quot;&gt;&lt;/span&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;Run&lt;/span&gt; &lt;span style=&quot;background: Yellow&quot;&gt;ws=&quot;en&quot;&gt;a&lt;/span&gt; &lt;span style=&quot;background: Yellow&quot;&gt;door&lt;/span&gt;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;/Run&gt;&lt;/span&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;/AStr&gt;&lt;/span&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;/Definition&gt;&lt;/span&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Gloss&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;AUni ws=&quot;en&quot;&gt;door&amp;lt;/AUni&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/Gloss&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MorphoSyntaxAnalysis&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;objsur guid=&quot;f63e03f0-ac9d-4b1b-980f-316bbb741f70&quot; t=&quot;r&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphoSyntaxAnalysis&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/ownseq&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/Senses&gt;&lt;br/&gt;&amp;lt;/LexEntry&gt;&lt;/div&gt;&lt;div class='alternative'&gt;user57@tpad2's changes: &amp;lt;LexEntry guid=&quot;bab7776e-531b-4ce1-997f-fa638c09e381&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DateCreated val=&quot;2012-7-20 13:46:3.625&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DateModified val=&quot;2012-7-20 13:46:3.625&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DoNotUseForParsing val=&quot;False&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;HomographNumber val=&quot;0&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;LexemeForm&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MoStemAllomorph guid=&quot;556f6e08-0fb2-4171-82e0-6dcdddf9490b&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Form&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;AUni ws=&quot;id&quot;&gt;pintu&amp;lt;/AUni&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/Form&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;IsAbstract val=&quot;False&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MorphType&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;objsur guid=&quot;d7f713e8-e8cf-11d3-9764-00c04f186933&quot; t=&quot;r&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphType&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MoStemAllomorph&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/LexemeForm&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;MorphoSyntaxAnalyses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MoStemMsa guid=&quot;f63e03f0-ac9d-4b1b-980f-316bbb741f70&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphoSyntaxAnalyses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;Senses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ownseq class=&quot;LexSense&quot; guid=&quot;dad069de-dfad-45f6-a5d2-449265adbc3a&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Gloss&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;AUni ws=&quot;en&quot;&gt;door&amp;lt;/AUni&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/Gloss&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MorphoSyntaxAnalysis&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;objsur guid=&quot;f63e03f0-ac9d-4b1b-980f-316bbb741f70&quot; t=&quot;r&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphoSyntaxAnalysis&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/ownseq&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/Senses&gt;&lt;br/&gt;&amp;lt;/LexEntry&gt;&lt;/div&gt;&lt;div class='mergechoice'&gt;The merger kept the change made by user57&lt;/div&gt;&lt;/body&gt;'
	contextPath='silfw://localhost/link?app=flex&amp;database=current&amp;server=&amp;tool=default&amp;guid=bab7776e-531b-4ce1-997f-fa638c09e381&amp;tag=&amp;label=Entry &quot;pintu&quot;'
	contextDataLabel='Entry &quot;pintu&quot;'>
	<MergeSituation
		alphaUserId='user57'
		betaUserId='user57@tpad2'
		alphaUserRevision='306520fcc148'
		betaUserRevision='5aa248710fbc'
		path='Linguistics\Lexicon\Lexicon.lexdb'
		conflictHandlingMode='WeWin' />
</conflict>]]></message>
		<message
			author='user57'
			status='closed'
			date='2012-07-20T22:49:03Z'
			guid='bf43783e-eca1-4b0f-bacd-6fe168d7d616'></message>
	</annotation>
</notes>";
                        File.WriteAllText(common.Path, commonData);

                        const string ourData =
                            @"<?xml version='1.0' encoding='utf-8'?>
<notes
	version='0'>
	<annotation
		class='mergeConflict'
		ref='silfw://localhost/link?app=flex&amp;database=current&amp;server=&amp;tool=default&amp;guid=bab7776e-531b-4ce1-997f-fa638c09e381&amp;tag=&amp;label=Entry &quot;pintu&quot;'
		guid='1cb66d60-90d5-4367-95b1-b7b41eb8986d'>
		<message
			author='merger'
			status='open'
			guid='ef89b532-5441-48a8-aea9-065b6ab5cfbd'
			date='2012-07-20T14:18:35Z'>Entry 'pintu': user57@tpad2 deleted this element, while user57 edited it. The automated merger kept the change made by user57.<![CDATA[<conflict
	typeGuid='3d9ba4ac-4a25-11df-9879-0800200c9a66'
	class='Chorus.merge.xml.generic.EditedVsRemovedElementConflict'
	relativeFilePath='Linguistics\Lexicon\Lexicon.lexdb'
	type='Removed Vs Edited Element Conflict'
	guid='ef89b532-5441-48a8-aea9-065b6ab5cfbd'
	date='2012-07-20T14:18:35Z'
	whoWon='user57'
	htmlDetails='&lt;head&gt;&lt;style type='text/css'&gt;&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;div class='description'&gt;Entry &quot;pintu&quot;: user57@tpad2 deleted this element, while user57 edited it. The automated merger kept the change made by user57.&lt;/div&gt;&lt;div class='alternative'&gt;user57's changes: &amp;lt;LexEntry guid=&quot;bab7776e-531b-4ce1-997f-fa638c09e381&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DateCreated val=&quot;2012-7-20 13:46:3.625&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DateModified val=&quot;2012-7-20 &lt;span style=&quot;text-decoration: line-through; color: red&quot;&gt;13:46:3.625&lt;/span&gt;&lt;span style=&quot;background: Yellow&quot;&gt;14:14:20.218&lt;/span&gt;&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DoNotUseForParsing val=&quot;False&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;HomographNumber val=&quot;0&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;LexemeForm&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MoStemAllomorph guid=&quot;556f6e08-0fb2-4171-82e0-6dcdddf9490b&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Form&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;AUni ws=&quot;id&quot;&gt;pintu&amp;lt;/AUni&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/Form&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;IsAbstract val=&quot;False&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MorphType&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;objsur guid=&quot;d7f713e8-e8cf-11d3-9764-00c04f186933&quot; t=&quot;r&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphType&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MoStemAllomorph&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/LexemeForm&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;MorphoSyntaxAnalyses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MoStemMsa guid=&quot;f63e03f0-ac9d-4b1b-980f-316bbb741f70&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphoSyntaxAnalyses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;Senses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ownseq class=&quot;LexSense&quot; guid=&quot;dad069de-dfad-45f6-a5d2-449265adbc3a&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;Definition&gt;&lt;/span&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;AStr&lt;/span&gt; &lt;span style=&quot;background: Yellow&quot;&gt;ws=&quot;en&quot;&gt;&lt;/span&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;Run&lt;/span&gt; &lt;span style=&quot;background: Yellow&quot;&gt;ws=&quot;en&quot;&gt;a&lt;/span&gt; &lt;span style=&quot;background: Yellow&quot;&gt;door&lt;/span&gt;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;/Run&gt;&lt;/span&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;/AStr&gt;&lt;/span&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;/Definition&gt;&lt;/span&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Gloss&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;AUni ws=&quot;en&quot;&gt;door&amp;lt;/AUni&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/Gloss&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MorphoSyntaxAnalysis&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;objsur guid=&quot;f63e03f0-ac9d-4b1b-980f-316bbb741f70&quot; t=&quot;r&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphoSyntaxAnalysis&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/ownseq&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/Senses&gt;&lt;br/&gt;&amp;lt;/LexEntry&gt;&lt;/div&gt;&lt;div class='alternative'&gt;user57@tpad2's changes: &amp;lt;LexEntry guid=&quot;bab7776e-531b-4ce1-997f-fa638c09e381&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DateCreated val=&quot;2012-7-20 13:46:3.625&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DateModified val=&quot;2012-7-20 13:46:3.625&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DoNotUseForParsing val=&quot;False&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;HomographNumber val=&quot;0&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;LexemeForm&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MoStemAllomorph guid=&quot;556f6e08-0fb2-4171-82e0-6dcdddf9490b&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Form&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;AUni ws=&quot;id&quot;&gt;pintu&amp;lt;/AUni&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/Form&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;IsAbstract val=&quot;False&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MorphType&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;objsur guid=&quot;d7f713e8-e8cf-11d3-9764-00c04f186933&quot; t=&quot;r&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphType&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MoStemAllomorph&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/LexemeForm&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;MorphoSyntaxAnalyses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MoStemMsa guid=&quot;f63e03f0-ac9d-4b1b-980f-316bbb741f70&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphoSyntaxAnalyses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;Senses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ownseq class=&quot;LexSense&quot; guid=&quot;dad069de-dfad-45f6-a5d2-449265adbc3a&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Gloss&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;AUni ws=&quot;en&quot;&gt;door&amp;lt;/AUni&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/Gloss&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MorphoSyntaxAnalysis&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;objsur guid=&quot;f63e03f0-ac9d-4b1b-980f-316bbb741f70&quot; t=&quot;r&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphoSyntaxAnalysis&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/ownseq&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/Senses&gt;&lt;br/&gt;&amp;lt;/LexEntry&gt;&lt;/div&gt;&lt;div class='mergechoice'&gt;The merger kept the change made by user57&lt;/div&gt;&lt;/body&gt;'
	contextPath='silfw://localhost/link?app=flex&amp;database=current&amp;server=&amp;tool=default&amp;guid=bab7776e-531b-4ce1-997f-fa638c09e381&amp;tag=&amp;label=Entry &quot;pintu&quot;'
	contextDataLabel='Entry &quot;pintu&quot;'>
	<MergeSituation
		alphaUserId='user57'
		betaUserId='user57@tpad2'
		alphaUserRevision='306520fcc148'
		betaUserRevision='5aa248710fbc'
		path='Linguistics\Lexicon\Lexicon.lexdb'
		conflictHandlingMode='WeWin' />
</conflict>]]></message>
		<message
			author='user57'
			status='closed'
			date='2012-07-20T22:49:03Z'
			guid='bf43783e-eca1-4b0f-bacd-6fe168d7d616'></message>
		<message
			author='user57'
			status='open'
			date='2012-07-20T23:11:24Z'
			guid='524786f4-8e27-4ebf-b7ea-02846723c2d8'>Chorus seems to have chosen the better gloss anyway.</message>
	</annotation>
</notes>";
                        File.WriteAllText(ours.Path, ourData);

                        const string theirData =
                            @"<?xml version='1.0' encoding='utf-8'?>
<notes
	version='0'>
	<annotation
		class='mergeConflict'
		ref='silfw://localhost/link?app=flex&amp;database=current&amp;server=&amp;tool=default&amp;guid=bab7776e-531b-4ce1-997f-fa638c09e381&amp;tag=&amp;label=Entry &quot;pintu&quot;'
		guid='1cb66d60-90d5-4367-95b1-b7b41eb8986d'>
		<message
			author='merger'
			status='open'
			guid='ef89b532-5441-48a8-aea9-065b6ab5cfbd'
			date='2012-07-20T14:18:35Z'>Entry 'pintu': user57@tpad2 deleted this element, while user57 edited it. The automated merger kept the change made by user57.<![CDATA[<conflict
	typeGuid='3d9ba4ac-4a25-11df-9879-0800200c9a66'
	class='Chorus.merge.xml.generic.EditedVsRemovedElementConflict'
	relativeFilePath='Linguistics\Lexicon\Lexicon.lexdb'
	type='Removed Vs Edited Element Conflict'
	guid='ef89b532-5441-48a8-aea9-065b6ab5cfbd'
	date='2012-07-20T14:18:35Z'
	whoWon='user57'
	htmlDetails='&lt;head&gt;&lt;style type='text/css'&gt;&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;div class='description'&gt;Entry &quot;pintu&quot;: user57@tpad2 deleted this element, while user57 edited it. The automated merger kept the change made by user57.&lt;/div&gt;&lt;div class='alternative'&gt;user57's changes: &amp;lt;LexEntry guid=&quot;bab7776e-531b-4ce1-997f-fa638c09e381&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DateCreated val=&quot;2012-7-20 13:46:3.625&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DateModified val=&quot;2012-7-20 &lt;span style=&quot;text-decoration: line-through; color: red&quot;&gt;13:46:3.625&lt;/span&gt;&lt;span style=&quot;background: Yellow&quot;&gt;14:14:20.218&lt;/span&gt;&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DoNotUseForParsing val=&quot;False&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;HomographNumber val=&quot;0&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;LexemeForm&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MoStemAllomorph guid=&quot;556f6e08-0fb2-4171-82e0-6dcdddf9490b&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Form&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;AUni ws=&quot;id&quot;&gt;pintu&amp;lt;/AUni&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/Form&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;IsAbstract val=&quot;False&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MorphType&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;objsur guid=&quot;d7f713e8-e8cf-11d3-9764-00c04f186933&quot; t=&quot;r&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphType&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MoStemAllomorph&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/LexemeForm&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;MorphoSyntaxAnalyses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MoStemMsa guid=&quot;f63e03f0-ac9d-4b1b-980f-316bbb741f70&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphoSyntaxAnalyses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;Senses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ownseq class=&quot;LexSense&quot; guid=&quot;dad069de-dfad-45f6-a5d2-449265adbc3a&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;Definition&gt;&lt;/span&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;AStr&lt;/span&gt; &lt;span style=&quot;background: Yellow&quot;&gt;ws=&quot;en&quot;&gt;&lt;/span&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;Run&lt;/span&gt; &lt;span style=&quot;background: Yellow&quot;&gt;ws=&quot;en&quot;&gt;a&lt;/span&gt; &lt;span style=&quot;background: Yellow&quot;&gt;door&lt;/span&gt;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;/Run&gt;&lt;/span&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;/AStr&gt;&lt;/span&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style=&quot;background: Yellow&quot;&gt;&amp;lt;/Definition&gt;&lt;/span&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Gloss&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;AUni ws=&quot;en&quot;&gt;door&amp;lt;/AUni&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/Gloss&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MorphoSyntaxAnalysis&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;objsur guid=&quot;f63e03f0-ac9d-4b1b-980f-316bbb741f70&quot; t=&quot;r&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphoSyntaxAnalysis&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/ownseq&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/Senses&gt;&lt;br/&gt;&amp;lt;/LexEntry&gt;&lt;/div&gt;&lt;div class='alternative'&gt;user57@tpad2's changes: &amp;lt;LexEntry guid=&quot;bab7776e-531b-4ce1-997f-fa638c09e381&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DateCreated val=&quot;2012-7-20 13:46:3.625&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DateModified val=&quot;2012-7-20 13:46:3.625&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;DoNotUseForParsing val=&quot;False&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;HomographNumber val=&quot;0&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;LexemeForm&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MoStemAllomorph guid=&quot;556f6e08-0fb2-4171-82e0-6dcdddf9490b&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Form&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;AUni ws=&quot;id&quot;&gt;pintu&amp;lt;/AUni&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/Form&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;IsAbstract val=&quot;False&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MorphType&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;objsur guid=&quot;d7f713e8-e8cf-11d3-9764-00c04f186933&quot; t=&quot;r&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphType&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MoStemAllomorph&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/LexemeForm&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;MorphoSyntaxAnalyses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MoStemMsa guid=&quot;f63e03f0-ac9d-4b1b-980f-316bbb741f70&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphoSyntaxAnalyses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;Senses&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;ownseq class=&quot;LexSense&quot; guid=&quot;dad069de-dfad-45f6-a5d2-449265adbc3a&quot;&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;Gloss&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;AUni ws=&quot;en&quot;&gt;door&amp;lt;/AUni&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/Gloss&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;MorphoSyntaxAnalysis&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;objsur guid=&quot;f63e03f0-ac9d-4b1b-980f-316bbb741f70&quot; t=&quot;r&quot; /&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/MorphoSyntaxAnalysis&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/ownseq&gt;&lt;br/&gt;&amp;nbsp;&amp;nbsp;&amp;lt;/Senses&gt;&lt;br/&gt;&amp;lt;/LexEntry&gt;&lt;/div&gt;&lt;div class='mergechoice'&gt;The merger kept the change made by user57&lt;/div&gt;&lt;/body&gt;'
	contextPath='silfw://localhost/link?app=flex&amp;database=current&amp;server=&amp;tool=default&amp;guid=bab7776e-531b-4ce1-997f-fa638c09e381&amp;tag=&amp;label=Entry &quot;pintu&quot;'
	contextDataLabel='Entry &quot;pintu&quot;'>
	<MergeSituation
		alphaUserId='user57'
		betaUserId='user57@tpad2'
		alphaUserRevision='306520fcc148'
		betaUserRevision='5aa248710fbc'
		path='Linguistics\Lexicon\Lexicon.lexdb'
		conflictHandlingMode='WeWin' />
</conflict>]]></message>
		<message
			author='user57'
			status='closed'
			date='2012-07-20T22:49:03Z'
			guid='bf43783e-eca1-4b0f-bacd-6fe168d7d616'></message>
		<message
			author='user57'
			status='closed'
			date='2012-07-20T23:11:27Z'
			guid='a0481907-3fff-45a2-bb1c-961c3198c86a'></message>
	</annotation>
</notes>";
                        File.WriteAllText(theirs.Path, theirData);

                        // Do it the new way.
                        _chorusNotesFileHandler.Do3WayMerge(new MergeOrder(ours.Path, common.Path, theirs.Path, new NullMergeSituation()));
                        var newWayResult = File.ReadAllText(ours.Path);
                        CheckResults(false, ourData, newWayResult);

                        // Do it the old way via XmlMerge.
                        var mergeSit = new MergeSituation(ours.Path, "Me", "8", "You", "9", MergeOrder.ConflictHandlingModeChoices.WeWin);
                        var merger   = new XmlMerger(mergeSit);
                        var listener = new ListenerForUnitTests();
                        merger.MergeStrategies.SetStrategy("annotation", ElementStrategy.CreateForKeyedElement("guid", false));
                        var messageStrategy = ElementStrategy.CreateForKeyedElement("guid", false);
                        messageStrategy.IsImmutable = true;
                        merger.MergeStrategies.SetStrategy("message", messageStrategy);
                        merger.EventListener = listener;
                        var ourDataNode = XmlUtilities.GetDocumentNodeFromRawXml(ourData.Replace("<?xml version='1.0' encoding='utf-8'?>", null).Trim(), new XmlDocument());
                        var mergeResult = merger.Merge(
                            ourDataNode.ParentNode, ourDataNode,
                            XmlUtilities.GetDocumentNodeFromRawXml(theirData.Replace("<?xml version='1.0' encoding='utf-8'?>", null).Trim(), new XmlDocument()),
                            XmlUtilities.GetDocumentNodeFromRawXml(commonData.Replace("<?xml version='1.0' encoding='utf-8'?>", null).Trim(), new XmlDocument()));
                        var oldWayResult = mergeResult.MergedNode.OuterXml;
                        CheckResults(false, ourData, oldWayResult);

                        // Compare old and new results.
                        CheckResults(true, newWayResult, oldWayResult);

                        using (var log = new ChorusNotesMergeEventListener(ours.Path))
                        {
                            // The purpose here is to make sure that the listener works correctly regarding maintaining CData.
                            // I (RandyR) saw a merged data set where the CData material was not maintained.
                        }
                        var result = File.ReadAllText(ours.Path);
                        CheckResults(true, newWayResult, result);

                        var doc = new XmlDocument();
                        doc.Load(ours.Path);
                        // This is how the AnnotationRepository class writes out an updated ChorusNotes file.
                        using (var writer = XmlWriter.Create(ours.Path, CanonicalXmlSettings.CreateXmlWriterSettings()))
                        {
                            doc.Save(writer);
                        }
                        CheckResults(true, result, File.ReadAllText(ours.Path));
                    }
        }
コード例 #10
0
        [Category("UnknownMonoIssue")]         // It insists on failing on mono, for some reason.
        public void EnsureRightPersonMadeChanges()
        {
            const string commonAncestor =
                @"<?xml version='1.0' encoding='utf-8'?>
<Lexicon>
	<header>
		<LexDb guid='2d23f428-83a9-44ba-90f1-9e3264b5b982' >
			<DateCreated val='2012-12-10 6:29:17.117' />
			<DateModified val='2012-12-10 6:29:17.117' />
			<IsHeadwordCitationForm val='True' />
			<IsBodyInSeparateSubentry val='True' />
		</LexDb>
	</header>
	<LexEntry guid='ffdc58c9-5cc3-469f-9118-9f18c0138d02'>
		<DateCreated val='2012-12-10 6:29:17.117' />
		<DateModified val='2012-12-10 6:29:17.117' />
		<HomographNumber val='1' />
		<DoNotUseForParsing val='True' />
		<ExcludeAsHeadword val='True' />
		<Senses>
			<ownseq class='LexSense' guid='97129e67-e0a5-47c4-a875-05c2b2e1b7df'>
				<Custom
					name='Paradigm'>
					<AStr
						ws='qaa-x-ezpi'>
						<Run
							ws='qaa-x-ezpi'>saklo, yzaklo, rzaklo, wzaklo, nzaklo, -</Run>
					</AStr>
				</Custom>
			</ownseq>
		</Senses>
	</LexEntry>
</Lexicon>";
            const string sue =
                @"<?xml version='1.0' encoding='utf-8'?>
<Lexicon>
	<header>
		<LexDb guid='2d23f428-83a9-44ba-90f1-9e3264b5b982' >
			<DateCreated val='2012-12-10 6:29:17.117' />
			<DateModified val='2012-12-10 6:29:17.117' />
			<IsHeadwordCitationForm val='True' />
			<IsBodyInSeparateSubentry val='True' />
		</LexDb>
	</header>
	<LexEntry guid='ffdc58c9-5cc3-469f-9118-9f18c0138d02'>
		<DateCreated val='2012-12-10 6:29:17.117' />
		<DateModified val='2012-12-10 6:29:17.117' />
		<HomographNumber val='1' />
		<DoNotUseForParsing val='True' />
		<ExcludeAsHeadword val='True' />
		<Senses>
			<ownseq class='LexSense' guid='97129e67-e0a5-47c4-a875-05c2b2e1b7df'>
				<Custom
					name='Paradigm'>
					<AStr
						ws='qaa-x-ezpi'>
						<Run
							ws='qaa-x-ezpi'>saglo, yzaglo, rzaglo, wzaglo, nzaglo, -</Run>
					</AStr>
				</Custom>
			</ownseq>
		</Senses>
	</LexEntry>
</Lexicon>";
            const string randy =
                @"<?xml version='1.0' encoding='utf-8'?>
<Lexicon>
	<header>
		<LexDb guid='2d23f428-83a9-44ba-90f1-9e3264b5b982' >
		</LexDb>
	</header>
	<LexEntry guid='ffdc58c9-5cc3-469f-9118-9f18c0138d02'>
		<Senses>
			<ownseq class='LexSense' guid='97129e67-e0a5-47c4-a875-05c2b2e1b7df'>
				<Custom
					name='Paradigm'>
					<AStr
						ws='zpi'>
						<Run
							ws='zpi'>saklo, yzaklo, rzaklo, wzaklo, nzaklo, -</Run>
					</AStr>
				</Custom>
			</ownseq>
		</Senses>
	</LexEntry>
</Lexicon>";

            var mdc = MetadataCache.TestOnlyNewCache;

            using (var sueRepo = new RepositoryWithFilesSetup("Sue", string.Format("{0}_01.{1}", SharedConstants.Lexicon, SharedConstants.Lexdb), commonAncestor))
            {
                var sueProjPath = sueRepo.ProjectFolder.Path;
                // Add model version number file.
                var modelVersionPathname = Path.Combine(sueProjPath, SharedConstants.ModelVersionFilename);
                File.WriteAllText(modelVersionPathname, AnnotationImages.kModelVersion);
                sueRepo.Repository.TestOnlyAddSansCommit(modelVersionPathname);
                // Add custom property data file.
                var customPropsPathname = Path.Combine(sueProjPath, SharedConstants.CustomPropertiesFilename);
                File.WriteAllText(customPropsPathname, CustomPropData);
                sueRepo.Repository.TestOnlyAddSansCommit(customPropsPathname);
                sueRepo.AddAndCheckIn();

                using (var randyRepo = RepositoryWithFilesSetup.CreateByCloning("Randy", sueRepo))
                {
                    // By doing the clone first, we get the common starting state in both repos.
                    sueRepo.WriteNewContentsToTestFile(sue);
                    sueRepo.AddAndCheckIn();

                    var mergeConflictsNotesFile = ChorusNotesMergeEventListener.GetChorusNotesFilePath(randyRepo.UserFile.Path);
                    Assert.IsFalse(File.Exists(mergeConflictsNotesFile), "ChorusNotes file should NOT have been in working set.");
                    randyRepo.WriteNewContentsToTestFile(randy);
                    randyRepo.CheckinAndPullAndMerge(sueRepo);
                    Assert.IsTrue(File.Exists(mergeConflictsNotesFile), "ChorusNotes file should have been in working set.");
                    var notesContents = File.ReadAllText(mergeConflictsNotesFile);
                    Assert.IsNotNullOrEmpty(notesContents);
                    Assert.That(notesContents, Is.StringContaining("Removed Vs Edited Element Conflict"));
                    Assert.That(notesContents, Is.StringContaining("Randy deleted this element"));
                    Assert.That(notesContents, Is.StringContaining("Sue edited it"));
                    Assert.That(notesContents, Is.StringContaining("The merger kept the change made by Sue."));
                    Assert.That(notesContents, Is.StringContaining("whoWon=\"Sue\""));
                    Assert.That(notesContents, Is.StringContaining("alphaUserId=\"Randy\""));
                    Assert.That(notesContents, Is.StringContaining("betaUserId=\"Sue\""));

                    // Make sure merged file has both alts.
                    var doc = XDocument.Load(randyRepo.UserFile.Path);
                    var customParadigmElement = doc.Root.Element("LexEntry").Element("Senses").Element("ownseq").Element("Custom");
                    var aStrElements          = customParadigmElement.Elements("AStr").ToList();
                    Assert.AreEqual(2, aStrElements.Count);
                    var aStrZpi = aStrElements.FirstOrDefault(el => el.Attribute("ws").Value == "zpi");
                    Assert.IsNotNull(aStrZpi);
                    Assert.IsTrue(aStrZpi.Element("Run").Value == "saklo, yzaklo, rzaklo, wzaklo, nzaklo, -");
                    var aStrEzpi = aStrElements.FirstOrDefault(el => el.Attribute("ws").Value == "qaa-x-ezpi");
                    Assert.IsNotNull(aStrEzpi);
                    Assert.IsTrue(aStrEzpi.Element("Run").Value == "saglo, yzaglo, rzaglo, wzaglo, nzaglo, -");
                }
            }
        }
コード例 #11
0
        [Category("UnknownMonoIssue")]         // Do3WayMerge is never called on Mono, for some reason.
        public void DictConfigMerge_DifferentUpradePathKeepsFileFormat()
        {
            const string commonAncestor = null;

            const string sue = @"<?xml version='1.0' encoding='utf-8'?>
<DictionaryConfiguration name='Root-based (complex forms as subentries)' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' allPublications='true' version='14' lastModified='2014-10-07'>
  <ConfigurationItem name='Main Entry' style='Dictionary-Normal' isEnabled='true' field='LexEntry' cssClassNameOverride='entry'>
  <ParagraphOptions paragraphStyle='Dictionary-Normal' continuationParagraphStyle='Dictionary-Continuation' />
	<ConfigurationItem name='Headword' between=' ' after='  ' style='Dictionary-Headword' isEnabled='true' field='MLHeadWord' cssClassNameOverride='mainheadword'>
	  <WritingSystemOptions writingSystemType='vernacular' displayWSAbreviation='false'>
		<Option id='vernacular' isEnabled='false'/>
		<Option id='fr' isEnabled='true' />
	  </WritingSystemOptions>
	</ConfigurationItem>
	<ConfigurationItem name='Variant Forms' before='(' between='; ' after=') ' isEnabled='true' field='VariantFormEntryBackRefs'>
	  <ListTypeOptions list='variant'>
		<Option isEnabled='true' id='b0000000-c40e-433e-80b5-31da08771344'/>
		<Option isEnabled='false' id='0c4663b3-4d9a-47af-b9a1-c8565d8112ed'/>
	  </ListTypeOptions>
	</ConfigurationItem>
  </ConfigurationItem>
</DictionaryConfiguration>";

            const string randy = @"<?xml version='1.0' encoding='utf-8'?>
<DictionaryConfiguration xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' name='Root-based (complex forms as subentries)' allPublications='true' version='17' lastModified='2014-10-07'>
  <ConfigurationItem name='Main Entry' style='Dictionary-Normal' isEnabled='true' field='LexEntry' cssClassNameOverride='entry'>
  <ParagraphOptions paragraphStyle='Dictionary-Normal' continuationParagraphStyle='Dictionary-Continuation' />
	<ConfigurationItem name='Headword' between=' ' after='  ' style='Dictionary-Headword' isEnabled='true' field='MLHeadWord' cssClassNameOverride='mainheadword'>
	  <WritingSystemOptions writingSystemType='vernacular' displayWSAbreviation='false'>
		<Option id='vernacular' isEnabled='true'/>
	  </WritingSystemOptions>
	</ConfigurationItem>
	<ConfigurationItem name='Variant Forms' before='(' between='; ' after=') ' isEnabled='true' field='VariantFormEntryBackRefs'>
	  <ListTypeOptions list='variant'>
		<Option isEnabled='false' id='b0000000-c40e-433e-80b5-31da08771344'/>
		<Option isEnabled='true' id='0c4663b3-4d9a-47af-b9a1-c8565d8112ed'/>
	  </ListTypeOptions>
	</ConfigurationItem>
  </ConfigurationItem>
</DictionaryConfiguration>";

            using (var tempFolder = new TemporaryFolder("Temp"))
            {
                // Copy the Dictionary Configuration Schema to where the Dictionary Configuration Handler Strategy looks
                var appsDir       = Path.GetDirectoryName(Utilities.StripFilePrefix(Assembly.GetExecutingAssembly().CodeBase));
                var xsdPath       = Path.Combine(appsDir, "TestData", "Language Explorer", "Configuration", SharedConstants.DictConfigSchemaFilename);
                var xsdPathInProj = Path.Combine(tempFolder.Path, SharedConstants.DictConfigSchemaFilename);
                File.Copy(xsdPath, xsdPathInProj, true);

                using (var sueRepo = new RepositorySetup("Sue", true))
                {
                    sueRepo.AddAndCheckinFile("unrelated.txt", "unrelated to SUT, here to get us rev 0 so repos are related");
                    using (var randyRepo = new RepositorySetup("Randy", sueRepo))
                    {
                        // By doing the clone before making Sue's changes, we get the common starting state in both repos.
                        sueRepo.AddAndCheckinFile(string.Format("root.{0}", SharedConstants.fwdictconfig), sue);

                        var randyDictConfigInRepoPath = Path.Combine(randyRepo.ProjectFolder.Path, string.Format("root.{0}", SharedConstants.fwdictconfig));
                        var mergeConflictsNotesFile   = ChorusNotesMergeEventListener.GetChorusNotesFilePath(randyDictConfigInRepoPath);
                        Assert.IsFalse(File.Exists(mergeConflictsNotesFile), "ChorusNotes file should NOT have been in working set.");
                        randyRepo.AddAndCheckinFile(string.Format("root.{0}", SharedConstants.fwdictconfig), randy);
                        randyRepo.CheckinAndPullAndMerge(sueRepo);
                        Assert.IsTrue(File.Exists(mergeConflictsNotesFile), "ChorusNotes file should have been in working set.");
                        var notesContents = File.ReadAllText(mergeConflictsNotesFile);
                        Assert.IsNotNullOrEmpty(notesContents);
                        Assert.That(notesContents, Is.StringContaining("Both added the same element, but with different content"));
                        Assert.That(notesContents, Is.StringContaining("The merger kept the change made by Randy."));
                        Assert.That(notesContents, Is.StringContaining("alphaUserId=\"Randy\""));
                        Assert.That(notesContents, Is.StringContaining("betaUserId=\"Sue\""));

                        // Make sure merged file has Randy's changes
                        var doc     = XDocument.Load(randyDictConfigInRepoPath);
                        var options = doc.Root.Element("ConfigurationItem").Elements("ConfigurationItem").Last(/*Variant Forms*/)
                                      .Element("ListTypeOptions").Elements("Option").ToList();
                        Assert.AreEqual(2, options.Count, "There should be two Variant Forms options");
                        Assert.AreEqual("b0000000-c40e-433e-80b5-31da08771344", options[0].Attribute("id").Value, "Options are out of order");
                        Assert.AreEqual("0c4663b3-4d9a-47af-b9a1-c8565d8112ed", options[1].Attribute("id").Value, "Options are out of order");
                        Assert.AreEqual("false", options[0].Attribute("isEnabled").Value, "First option should be disabled");
                        Assert.AreEqual("true", options[1].Attribute("isEnabled").Value, "Second option should be enabled");

                        // Make sure merged file does *not* have Sue's changes
                        options = doc.Root.Element("ConfigurationItem").Element("ConfigurationItem" /*Headword*/)
                                  .Element("WritingSystemOptions").Elements("Option").ToList();
                        Assert.AreEqual(1, options.Count, "There should be only one WS Option");
                        Assert.AreEqual("vernacular", options[0].Attribute("id").Value, "should be default vernacular");
                        Assert.AreEqual("true", options[0].Attribute("isEnabled").Value, "should be enabled");

                        // Make sure the merged file has proper xsd namespace attributes
                        var xsiAttr = doc.Root.Attribute("xsi");
                        var xsdAttr = doc.Root.Attribute("xsd");
                        Assert.Null(xsiAttr, "xsi missing namespace");
                        Assert.Null(xsdAttr, "xsd missing namespace");
                        //
                        XNamespace xsiNs = "http://www.w3.org/2001/XMLSchema-instance";
                        XNamespace xsdNs = "http://www.w3.org/2001/XMLSchema";
                        xsiAttr = doc.Root.Attribute(xsiNs + "xsi");
                        xsdAttr = doc.Root.Attribute(xsdNs + "xsd");
                        Assert.Null(xsiAttr, "xsi attribute missing entirely from result");
                        Assert.Null(xsdAttr, "xsd attribute missing entirely from result");
                    }
                }
            }
        }