diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlCommentFold.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlCommentFold.cs
new file mode 100644
index 0000000000..70b97f287c
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlCommentFold.cs
@@ -0,0 +1,72 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Xml;
+using ICSharpCode.SharpDevelop.Dom;
+
+namespace ICSharpCode.XmlEditor
+{
+ public class XmlCommentFold
+ {
+ string[] lines = new string[0];
+ string comment = String.Empty;
+ DomRegion commentRegion;
+ string displayText;
+
+ const string CommentStartTag = "";
+
+ public XmlCommentFold(XmlTextReader reader)
+ {
+ ReadComment(reader);
+ }
+
+ void ReadComment(XmlTextReader reader)
+ {
+ GetCommentLines(reader);
+ GetCommentRegion(reader, lines);
+ GetCommentDisplayText(lines);
+ }
+
+ void GetCommentLines(XmlTextReader reader)
+ {
+ comment = reader.Value.Replace("\r\n", "\n");
+ lines = comment.Split('\n');
+ }
+
+ void GetCommentRegion(XmlTextReader reader, string[] lines)
+ {
+ int startColumn = reader.LinePosition - CommentStartTag.Length;
+ int startLine = reader.LineNumber;
+
+ string lastLine = lines[lines.Length - 1];
+ int endColumn = lastLine.Length + startColumn + CommentEndTag.Length;
+ int endLine = startLine + lines.Length - 1;
+
+ commentRegion = new DomRegion(startLine, startColumn, endLine, endColumn);
+ }
+
+ void GetCommentDisplayText(string[] lines)
+ {
+ string firstLine = String.Empty;
+ if (lines.Length > 0) {
+ firstLine = lines[0];
+ }
+ displayText = String.Concat("");
+ }
+
+ public FoldingRegion CreateFoldingRegion()
+ {
+ return new FoldingRegion(displayText, commentRegion);
+ }
+
+ public bool IsSingleLine {
+ get { return commentRegion.BeginLine == commentRegion.EndLine; }
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlElementFold.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlElementFold.cs
new file mode 100644
index 0000000000..5f984ef4bb
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlElementFold.cs
@@ -0,0 +1,151 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Text;
+using System.Xml;
+using ICSharpCode.SharpDevelop.Dom;
+
+namespace ICSharpCode.XmlEditor
+{
+ public class XmlElementFold
+ {
+ int line = 0;
+ int column = 0;
+
+ int endLine = 0;
+ int endColumn = 0;
+
+ string prefix = String.Empty;
+ string name = String.Empty;
+ string qualifiedElementName = String.Empty;
+ string elementDisplayText = String.Empty;
+ string elementWithAttributesDisplayText = String.Empty;
+
+ public void ReadStart(XmlTextReader reader)
+ {
+ // Take off 1 from the line position returned
+ // from the xml since it points to the start
+ // of the element name and not the beginning
+ // tag.
+ column = reader.LinePosition - 1;
+ line = reader.LineNumber;
+
+ prefix = reader.Prefix;
+ name = reader.LocalName;
+
+ GetQualifiedElementName();
+ GetElementDisplayText(qualifiedElementName);
+ GetElementWithAttributesDisplayText(reader);
+ }
+
+ void GetQualifiedElementName()
+ {
+ if (prefix.Length > 0) {
+ qualifiedElementName = String.Format("{0}:{1}", prefix, name);
+ } else {
+ qualifiedElementName = name;
+ }
+ }
+
+ void GetElementDisplayText(string qualifiedName)
+ {
+ elementDisplayText = String.Format("<{0}>", qualifiedName);
+ }
+
+ ///
+ /// Gets the element's attributes as a string on one line that will
+ /// be displayed when the element is folded.
+ ///
+ void GetElementWithAttributesDisplayText(XmlTextReader reader)
+ {
+ string attributesDisplayText = GetAttributesDisplayText(reader);
+ if (String.IsNullOrEmpty(attributesDisplayText)) {
+ elementWithAttributesDisplayText = elementDisplayText;
+ } else {
+ elementWithAttributesDisplayText = String.Format("<{0} {1}>", qualifiedElementName, attributesDisplayText);
+ }
+ }
+
+ string GetAttributesDisplayText(XmlTextReader reader)
+ {
+ StringBuilder text = new StringBuilder();
+
+ for (int i = 0; i < reader.AttributeCount; ++i) {
+ reader.MoveToAttribute(i);
+
+ text.Append(reader.Name);
+ text.Append("=");
+ text.Append(reader.QuoteChar.ToString());
+ text.Append(XmlEncodeAttributeValue(reader.Value, reader.QuoteChar));
+ text.Append(reader.QuoteChar.ToString());
+
+ // Append a space if this is not the
+ // last attribute.
+ if (!IsLastAttributeIndex(i, reader)) {
+ text.Append(" ");
+ }
+ }
+
+ return text.ToString();
+ }
+
+ ///
+ /// Xml encode the attribute string since the string returned from
+ /// the XmlTextReader is the plain unencoded string and .NET
+ /// does not provide us with an xml encode method.
+ ///
+ static string XmlEncodeAttributeValue(string attributeValue, char quoteChar)
+ {
+ StringBuilder encodedValue = new StringBuilder(attributeValue);
+
+ encodedValue.Replace("&", "&");
+ encodedValue.Replace("<", "<");
+ encodedValue.Replace(">", ">");
+
+ if (quoteChar == '"') {
+ encodedValue.Replace("\"", """);
+ } else {
+ encodedValue.Replace("'", "'");
+ }
+
+ return encodedValue.ToString();
+ }
+
+ bool IsLastAttributeIndex(int attributeIndex, XmlTextReader reader)
+ {
+ return attributeIndex == (reader.AttributeCount - 1);
+ }
+
+ public void ReadEnd(XmlTextReader reader)
+ {
+ endLine = reader.LineNumber;
+ int columnAfterEndTag = reader.LinePosition + qualifiedElementName.Length + 1;
+ endColumn = columnAfterEndTag;
+ }
+
+ public FoldingRegion CreateFoldingRegion()
+ {
+ return CreateFoldingRegion(elementDisplayText);
+ }
+
+ FoldingRegion CreateFoldingRegion(string displayText)
+ {
+ DomRegion region = new DomRegion(line, column, endLine, endColumn);
+ return new FoldingRegion(displayText, region);
+ }
+
+ public FoldingRegion CreateFoldingRegionWithAttributes()
+ {
+ return CreateFoldingRegion(elementWithAttributesDisplayText);
+ }
+
+ public bool IsSingleLine {
+ get { return line == endLine; }
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlFoldParser.cs b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlFoldParser.cs
new file mode 100644
index 0000000000..f5f7c72cc4
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Project/Src/XmlFoldParser.cs
@@ -0,0 +1,161 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using System.Xml;
+
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
+
+namespace ICSharpCode.XmlEditor
+{
+ public class XmlFoldParser : IParser
+ {
+ string[] lexerTags = new string[0];
+ DefaultXmlFileExtensions extensions;
+ XmlTextReader reader;
+ List folds;
+ Stack elementFoldStack;
+ XmlEditorOptions options;
+
+ public XmlFoldParser(DefaultXmlFileExtensions extensions, XmlEditorOptions options)
+ {
+ this.extensions = extensions;
+ this.options = options;
+ }
+
+ public XmlFoldParser()
+ : this(new DefaultXmlFileExtensions(), XmlEditorService.XmlEditorOptions)
+ {
+ }
+
+ public string[] LexerTags {
+ get { return lexerTags; }
+ set { lexerTags = value; }
+ }
+
+ public LanguageProperties Language {
+ get { return LanguageProperties.None; }
+ }
+
+ public IExpressionFinder CreateExpressionFinder(string fileName)
+ {
+ return null;
+ }
+
+ public bool CanParse(string fileName)
+ {
+ return extensions.Contains(Path.GetExtension(fileName).ToLowerInvariant());
+ }
+
+ public bool CanParse(IProject project)
+ {
+ return true;
+ }
+
+ public IResolver CreateResolver()
+ {
+ return null;
+ }
+
+ public ICompilationUnit Parse(IProjectContent projectContent, string fileName, ITextBuffer fileContent)
+ {
+ DefaultCompilationUnit unit = new DefaultCompilationUnit(projectContent);
+ unit.FileName = fileName;
+ GetFolds(fileContent.CreateReader());
+ unit.FoldingRegions.AddRange(folds);
+ return unit;
+ }
+
+ void GetFolds(TextReader textReader)
+ {
+ folds = new List();
+ elementFoldStack = new Stack();
+
+ try {
+ reader = new XmlTextReader(textReader);
+ reader.Namespaces = false;
+ while (reader.Read()) {
+ switch (reader.NodeType) {
+ case XmlNodeType.Element:
+ AddElementFoldToStackIfNotEmptyElement();
+ break;
+
+ case XmlNodeType.EndElement:
+ CreateElementFoldingRegionIfNotSingleLine();
+ break;
+
+ case XmlNodeType.Comment:
+ CreateCommentFoldingRegionIfNotSingleLine();
+ break;
+ }
+ }
+ } catch (Exception ex) {
+// // If the xml is not well formed keep the foldings
+// // that already exist in the document.
+// //return new List(document.FoldingManager.FoldMarker);
+// return new List();
+ Console.WriteLine(ex.ToString());
+ }
+
+ folds.Sort(CompareFoldingRegion);
+ }
+
+ void AddElementFoldToStackIfNotEmptyElement()
+ {
+ if (!reader.IsEmptyElement) {
+ XmlElementFold fold = new XmlElementFold();
+ fold.ReadStart(reader);
+ elementFoldStack.Push(fold);
+ }
+ }
+
+ void CreateElementFoldingRegionIfNotSingleLine()
+ {
+ XmlElementFold fold = elementFoldStack.Pop();
+ fold.ReadEnd(reader);
+ if (!fold.IsSingleLine) {
+ FoldingRegion foldingRegion = CreateFoldingRegion(fold);
+ folds.Add(foldingRegion);
+ }
+ }
+
+ FoldingRegion CreateFoldingRegion(XmlElementFold fold)
+ {
+ if (options.ShowAttributesWhenFolded) {
+ return fold.CreateFoldingRegionWithAttributes();
+ }
+ return fold.CreateFoldingRegion();
+ }
+
+ ///
+ /// Creates a comment fold if the comment spans more than one line.
+ ///
+ /// The text displayed when the comment is folded is the first
+ /// line of the comment.
+ void CreateCommentFoldingRegionIfNotSingleLine()
+ {
+ XmlCommentFold fold = new XmlCommentFold(reader);
+ if (!fold.IsSingleLine) {
+ folds.Add(fold.CreateFoldingRegion());
+ }
+ }
+
+ int CompareFoldingRegion(FoldingRegion lhs, FoldingRegion rhs)
+ {
+ int compareBeginLine = lhs.Region.BeginLine.CompareTo(rhs.Region.BeginLine);
+ if (compareBeginLine == 0) {
+ return lhs.Region.BeginColumn.CompareTo(rhs.Region.BeginColumn);
+ }
+ return compareBeginLine;
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.addin b/src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.addin
index 237a88213c..371e4b96c4 100644
--- a/src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.addin
+++ b/src/AddIns/DisplayBindings/XmlEditor/Project/XmlEditor.addin
@@ -19,6 +19,12 @@
+
+
+
+
+
@@ -131,6 +132,8 @@
+
+
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/AttributeTextInFoldIsXmlEncodedTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/AttributeTextInFoldIsXmlEncodedTestFixture.cs
new file mode 100644
index 0000000000..e0380c8e5c
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/AttributeTextInFoldIsXmlEncodedTestFixture.cs
@@ -0,0 +1,103 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.XmlEditor;
+using NUnit.Framework;
+using XmlEditor.Tests.Utils;
+
+namespace XmlEditor.Tests.Folding
+{
+ [TestFixture]
+ public class AttributeTextInFoldIsXmlEncodedTestFixture
+ {
+ XmlFoldParser parser;
+ ICompilationUnit unit;
+ DefaultXmlFileExtensions extensions;
+ DefaultProjectContent projectContent;
+ MockTextBuffer textBuffer;
+ XmlEditorOptions options;
+
+ [SetUp]
+ public void Init()
+ {
+ projectContent = new DefaultProjectContent();
+ extensions = new DefaultXmlFileExtensions(null);
+ options = new XmlEditorOptions(new Properties());
+ parser = new XmlFoldParser(extensions, options);
+ }
+
+ void ParseWithShowAttributesSetToTrue(string xml)
+ {
+ options.ShowAttributesWhenFolded = true;
+
+ textBuffer = new MockTextBuffer(xml);
+ unit = parser.Parse(projectContent, @"d:\projects\a.xml", textBuffer);
+ }
+
+ [Test]
+ public void FoldAttributeTextHasSingleQuoteEncoded()
+ {
+ string xml =
+ "\r\n" +
+ "";
+ ParseWithShowAttributesSetToTrue(xml);
+
+ Assert.AreEqual("", unit.FoldingRegions[0].Name);
+ }
+
+ [Test]
+ public void FoldAttributeTextHasDoubleQuoteEncoded()
+ {
+ string xml =
+ "\r\n" +
+ "";
+ ParseWithShowAttributesSetToTrue(xml);
+
+ Assert.AreEqual("", unit.FoldingRegions[0].Name);
+ }
+
+ [Test]
+ public void FoldAttributeTextHasAmpersandEncoded()
+ {
+ string xml =
+ "\r\n" +
+ "";
+ ParseWithShowAttributesSetToTrue(xml);
+
+ Assert.AreEqual("", unit.FoldingRegions[0].Name);
+ }
+
+ [Test]
+ public void FoldAttributeTextHasLessThanTagEncoded()
+ {
+ string xml =
+ "\r\n" +
+ "";
+ ParseWithShowAttributesSetToTrue(xml);
+
+ Assert.AreEqual("", unit.FoldingRegions[0].Name);
+ }
+
+ [Test]
+ public void FoldAttributeTextHasGreaterThanTagEncoded()
+ {
+ string xml =
+ "\r\n" +
+ "";
+ ParseWithShowAttributesSetToTrue(xml);
+
+ Assert.AreEqual("", unit.FoldingRegions[0].Name);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/EmptyCommentDoesNotCreateFoldTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/EmptyCommentDoesNotCreateFoldTestFixture.cs
new file mode 100644
index 0000000000..39841909d0
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/EmptyCommentDoesNotCreateFoldTestFixture.cs
@@ -0,0 +1,63 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.XmlEditor;
+using NUnit.Framework;
+using XmlEditor.Tests.Utils;
+
+namespace XmlEditor.Tests.Folding
+{
+ [TestFixture]
+ public class EmptyCommentDoesNotCreateFoldTestFixture
+ {
+ XmlFoldParser parser;
+ ICompilationUnit unit;
+ DefaultXmlFileExtensions extensions;
+ DefaultProjectContent projectContent;
+
+ [SetUp]
+ public void Init()
+ {
+ string xml =
+ "\r\n" +
+ "\r\n" +
+ "";
+
+ projectContent = new DefaultProjectContent();
+ MockTextBuffer textBuffer = new MockTextBuffer(xml);
+
+ extensions = new DefaultXmlFileExtensions(null);
+ XmlEditorOptions options = new XmlEditorOptions(new Properties());
+ parser = new XmlFoldParser(extensions, options);
+ unit = parser.Parse(projectContent, @"d:\projects\a.xml", textBuffer);
+ }
+
+ [Test]
+ public void CompilationUnitHasOneFold()
+ {
+ Assert.AreEqual(1, unit.FoldingRegions.Count);
+ }
+
+ [Test]
+ public void FoldRegionContainsRootElement()
+ {
+ int beginLine = 2;
+ int beginColumn = 1;
+ int endLine = 3;
+ int endColumn =8;
+ DomRegion expectedRegion = new DomRegion(beginLine, beginColumn, endLine, endColumn);
+ Assert.AreEqual(expectedRegion, unit.FoldingRegions[0].Region);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/FoldParserParsesInvalidXmlTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/FoldParserParsesInvalidXmlTestFixture.cs
new file mode 100644
index 0000000000..bb3e766f37
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/FoldParserParsesInvalidXmlTestFixture.cs
@@ -0,0 +1,46 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.XmlEditor;
+using NUnit.Framework;
+using XmlEditor.Tests.Utils;
+
+namespace XmlEditor.Tests.Folding
+{
+ [TestFixture]
+ public class FoldParserParsesInvalidXmlTestFixture
+ {
+ XmlFoldParser parser;
+ ICompilationUnit unit;
+ DefaultProjectContent projectContent;
+
+ [Test]
+ public void ParseMethodDoesNotThrowExceptionWhenParsingBadXml()
+ {
+ string xml =
+ "\r\n" +
+ "";
+
+ projectContent = new DefaultProjectContent();
+ MockTextBuffer textBuffer = new MockTextBuffer(xml);
+
+ DefaultXmlFileExtensions extensions = new DefaultXmlFileExtensions(null);
+ XmlEditorOptions options = new XmlEditorOptions(new Properties());
+ parser = new XmlFoldParser(extensions, options);
+
+ Assert.DoesNotThrow(delegate { unit = parser.Parse(projectContent, @"d:\projects\a.xml", textBuffer); });
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/MultiLineCommentFoldTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/MultiLineCommentFoldTestFixture.cs
new file mode 100644
index 0000000000..30d173e61b
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/MultiLineCommentFoldTestFixture.cs
@@ -0,0 +1,68 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.XmlEditor;
+using NUnit.Framework;
+using XmlEditor.Tests.Utils;
+
+namespace XmlEditor.Tests.Folding
+{
+ [TestFixture]
+ public class MultiLineCommentFoldTestFixture
+ {
+ XmlFoldParser parser;
+ ICompilationUnit unit;
+ DefaultXmlFileExtensions extensions;
+ DefaultProjectContent projectContent;
+
+ [SetUp]
+ public void Init()
+ {
+ string xml =
+ "";
+
+ projectContent = new DefaultProjectContent();
+ MockTextBuffer textBuffer = new MockTextBuffer(xml);
+
+ extensions = new DefaultXmlFileExtensions(null);
+ XmlEditorOptions options = new XmlEditorOptions(new Properties());
+ parser = new XmlFoldParser(extensions, options);
+ unit = parser.Parse(projectContent, @"d:\projects\a.xml", textBuffer);
+ }
+
+ [Test]
+ public void FoldingRegionsHasOneFold()
+ {
+ Assert.AreEqual(1, unit.FoldingRegions.Count);
+ }
+
+ [Test]
+ public void FoldNameIsCommentTagsWithFirstLineOfTextBetween()
+ {
+ Assert.AreEqual("", unit.FoldingRegions[0].Name);
+ }
+
+ [Test]
+ public void FoldRegionContainsEntireComment()
+ {
+ int beginLine = 1;
+ int beginColumn = 1;
+ int endLine = 2;
+ int endColumn = 16;
+ DomRegion expectedRegion = new DomRegion(beginLine, beginColumn, endLine, endColumn);
+ Assert.AreEqual(expectedRegion, unit.FoldingRegions[0].Region);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/QualifiedElementFoldTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/QualifiedElementFoldTestFixture.cs
new file mode 100644
index 0000000000..433e5a0fd0
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/QualifiedElementFoldTestFixture.cs
@@ -0,0 +1,64 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.XmlEditor;
+using NUnit.Framework;
+using XmlEditor.Tests.Utils;
+
+namespace XmlEditor.Tests.Folding
+{
+ [TestFixture]
+ public class QualifiedElementFoldTestFixture
+ {
+ XmlFoldParser parser;
+ ICompilationUnit unit;
+ DefaultXmlFileExtensions extensions;
+ DefaultProjectContent projectContent;
+ MockTextBuffer textBuffer;
+ XmlEditorOptions options;
+
+ [SetUp]
+ public void Init()
+ {
+ string xml =
+ "\r\n" +
+ "";
+
+ projectContent = new DefaultProjectContent();
+ textBuffer = new MockTextBuffer(xml);
+ extensions = new DefaultXmlFileExtensions(null);
+ options = new XmlEditorOptions(new Properties());
+
+ parser = new XmlFoldParser(extensions, options);
+ unit = parser.Parse(projectContent, @"a.xml", textBuffer);
+ }
+
+ [Test]
+ public void FoldNameContainsFullyQualifiedElementName()
+ {
+ Assert.AreEqual("", unit.FoldingRegions[0].Name);
+ }
+
+ [Test]
+ public void FoldRegionContainsRootElement()
+ {
+ int beginLine = 1;
+ int beginColumn = 1;
+ int endLine = 2;
+ int endColumn = 13;
+ DomRegion expectedRegion = new DomRegion(beginLine, beginColumn, endLine, endColumn);
+ Assert.AreEqual(expectedRegion, unit.FoldingRegions[0].Region);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/QualifiedElementWithNoDefinedNamespaceFoldTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/QualifiedElementWithNoDefinedNamespaceFoldTestFixture.cs
new file mode 100644
index 0000000000..1593b5af5e
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/QualifiedElementWithNoDefinedNamespaceFoldTestFixture.cs
@@ -0,0 +1,66 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+using System.Xml.Schema;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.XmlEditor;
+using NUnit.Framework;
+using XmlEditor.Tests.Utils;
+
+namespace XmlEditor.Tests.Folding
+{
+ [TestFixture]
+ public class QualifiedElementWithNoDefinedNamespaceFoldTestFixture
+ {
+ XmlFoldParser parser;
+ ICompilationUnit unit;
+ DefaultXmlFileExtensions extensions;
+ DefaultProjectContent projectContent;
+ MockTextBuffer textBuffer;
+ XmlEditorOptions options;
+
+ [SetUp]
+ public void Init()
+ {
+ string xml =
+ "\r\n" +
+ "";
+
+ projectContent = new DefaultProjectContent();
+ textBuffer = new MockTextBuffer(xml);
+ extensions = new DefaultXmlFileExtensions(null);
+ options = new XmlEditorOptions(new Properties());
+
+ parser = new XmlFoldParser(extensions, options);
+ unit = parser.Parse(projectContent, @"a.xml", textBuffer);
+ }
+
+ [Test]
+ public void FoldNameContainsFullyQualifiedElementName()
+ {
+ Assert.AreEqual("", unit.FoldingRegions[0].Name);
+ }
+
+ [Test]
+ public void FoldRegionContainsRootElement()
+ {
+ int beginLine = 1;
+ int beginColumn = 1;
+ int endLine = 2;
+ int endColumn = 10;
+ DomRegion expectedRegion = new DomRegion(beginLine, beginColumn, endLine, endColumn);
+ Assert.AreEqual(expectedRegion, unit.FoldingRegions[0].Region);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/ShowElementAttributesForElementWithNoAttributesTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/ShowElementAttributesForElementWithNoAttributesTestFixture.cs
new file mode 100644
index 0000000000..2da4d00e28
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/ShowElementAttributesForElementWithNoAttributesTestFixture.cs
@@ -0,0 +1,54 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.XmlEditor;
+using NUnit.Framework;
+using XmlEditor.Tests.Utils;
+
+namespace XmlEditor.Tests.Folding
+{
+ [TestFixture]
+ public class ShowElementAttributesForElementWithNoAttributesTestFixture
+ {
+ XmlFoldParser parser;
+ ICompilationUnit unit;
+ DefaultXmlFileExtensions extensions;
+ DefaultProjectContent projectContent;
+ MockTextBuffer textBuffer;
+ XmlEditorOptions options;
+
+ [SetUp]
+ public void Init()
+ {
+ string xml =
+ "\r\n" +
+ "";
+
+ projectContent = new DefaultProjectContent();
+ textBuffer = new MockTextBuffer(xml);
+ extensions = new DefaultXmlFileExtensions(null);
+ options = new XmlEditorOptions(new Properties());
+ options.ShowAttributesWhenFolded = true;
+
+ parser = new XmlFoldParser(extensions, options);
+ unit = parser.Parse(projectContent, @"d:\projects\a.xml", textBuffer);
+ }
+
+ [Test]
+ public void FoldNameIsElementNameOnlyWithNoExtraSpaceAtTheEnd()
+ {
+ Assert.AreEqual("", unit.FoldingRegions[0].Name);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/ShowElementAttributesInFoldTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/ShowElementAttributesInFoldTestFixture.cs
new file mode 100644
index 0000000000..2c1d40fc72
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/ShowElementAttributesInFoldTestFixture.cs
@@ -0,0 +1,89 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.XmlEditor;
+using NUnit.Framework;
+using XmlEditor.Tests.Utils;
+
+namespace XmlEditor.Tests.Folding
+{
+ [TestFixture]
+ public class ShowElementAttributesInFoldTestFixture
+ {
+ XmlFoldParser parser;
+ ICompilationUnit unit;
+ DefaultXmlFileExtensions extensions;
+ DefaultProjectContent projectContent;
+ MockTextBuffer textBuffer;
+ XmlEditorOptions options;
+
+ [SetUp]
+ public void Init()
+ {
+ string xml =
+ "\r\n" +
+ "";
+
+ projectContent = new DefaultProjectContent();
+ textBuffer = new MockTextBuffer(xml);
+ extensions = new DefaultXmlFileExtensions(null);
+ options = new XmlEditorOptions(new Properties());
+ }
+
+ void ParseWithShowAttributesSetToTrue()
+ {
+ options.ShowAttributesWhenFolded = true;
+ ParseXml();
+ }
+
+ void ParseXml()
+ {
+ parser = new XmlFoldParser(extensions, options);
+ unit = parser.Parse(projectContent, @"d:\projects\a.xml", textBuffer);
+ }
+
+ void ParseWithShowAttributesSetToFalse()
+ {
+ options.ShowAttributesWhenFolded = false;
+ ParseXml();
+ }
+
+ [Test]
+ public void FoldNameIsElementNameWithAttributesWhenShowAttributesIsTrue()
+ {
+ ParseWithShowAttributesSetToTrue();
+ Assert.AreEqual("", unit.FoldingRegions[0].Name);
+ }
+
+ [Test]
+ public void FoldNameIsElementNameOnlyWhenShowAttributesIsFalse()
+ {
+ ParseWithShowAttributesSetToFalse();
+ Assert.AreEqual("", unit.FoldingRegions[0].Name);
+ }
+
+ [Test]
+ public void FoldRegionContainsRootElement()
+ {
+ ParseWithShowAttributesSetToTrue();
+
+ int beginLine = 1;
+ int beginColumn = 1;
+ int endLine = 2;
+ int endColumn = 8;
+ DomRegion expectedRegion = new DomRegion(beginLine, beginColumn, endLine, endColumn);
+ Assert.AreEqual(expectedRegion, unit.FoldingRegions[0].Region);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/SingleEmptyElementFoldTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/SingleEmptyElementFoldTestFixture.cs
new file mode 100644
index 0000000000..378862c819
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/SingleEmptyElementFoldTestFixture.cs
@@ -0,0 +1,57 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.XmlEditor;
+using NUnit.Framework;
+using XmlEditor.Tests.Utils;
+
+namespace XmlEditor.Tests.Folding
+{
+ [TestFixture]
+ public class SingleEmptyElementFoldTestFixture
+ {
+ XmlFoldParser parser;
+ ICompilationUnit unit;
+ DefaultProjectContent projectContent;
+
+ [SetUp]
+ public void Init()
+ {
+ string xml =
+ "\r\n" +
+ " \r\n" +
+ "";
+
+ projectContent = new DefaultProjectContent();
+ MockTextBuffer textBuffer = new MockTextBuffer(xml);
+
+ DefaultXmlFileExtensions extensions = new DefaultXmlFileExtensions(null);
+ XmlEditorOptions options = new XmlEditorOptions(new Properties());
+ parser = new XmlFoldParser(extensions, options);
+ unit = parser.Parse(projectContent, @"d:\projects\a.xml", textBuffer);
+ }
+
+ [Test]
+ public void FoldRegionCoversRootElement()
+ {
+ int beginLine = 1;
+ int endLine = 3;
+ int beginCol = 1;
+ int endCol = 8;
+ DomRegion expectedRegion = new DomRegion(beginLine, beginCol, endLine, endCol);
+
+ Assert.AreEqual(expectedRegion, unit.FoldingRegions[0].Region);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/SingleLineCommentDoesNotCreateFoldTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/SingleLineCommentDoesNotCreateFoldTestFixture.cs
new file mode 100644
index 0000000000..fd62d3dab7
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/SingleLineCommentDoesNotCreateFoldTestFixture.cs
@@ -0,0 +1,49 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.XmlEditor;
+using NUnit.Framework;
+using XmlEditor.Tests.Utils;
+
+namespace XmlEditor.Tests.Folding
+{
+ [TestFixture]
+ public class SingleLineCommentDoesNotCreateFoldTestFixture
+ {
+ XmlFoldParser parser;
+ ICompilationUnit unit;
+ DefaultXmlFileExtensions extensions;
+ DefaultProjectContent projectContent;
+
+ [SetUp]
+ public void Init()
+ {
+ string xml = "";
+
+ projectContent = new DefaultProjectContent();
+ MockTextBuffer textBuffer = new MockTextBuffer(xml);
+
+ extensions = new DefaultXmlFileExtensions(null);
+ XmlEditorOptions options = new XmlEditorOptions(new Properties());
+ parser = new XmlFoldParser(extensions, options);
+ unit = parser.Parse(projectContent, @"d:\projects\a.xml", textBuffer);
+ }
+
+ [Test]
+ public void CompilationUnitHasNoFolds()
+ {
+ Assert.AreEqual(0, unit.FoldingRegions.Count);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/SingleLineElementDoesNotCreateFoldTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/SingleLineElementDoesNotCreateFoldTestFixture.cs
new file mode 100644
index 0000000000..2600aaf65b
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/SingleLineElementDoesNotCreateFoldTestFixture.cs
@@ -0,0 +1,63 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.XmlEditor;
+using NUnit.Framework;
+using XmlEditor.Tests.Utils;
+
+namespace XmlEditor.Tests.Folding
+{
+ [TestFixture]
+ public class SingleLineElementDoesNotCreateFoldTestFixture
+ {
+ XmlFoldParser parser;
+ ICompilationUnit unit;
+ DefaultProjectContent projectContent;
+
+ [SetUp]
+ public void Init()
+ {
+ string xml =
+ "\r\n" +
+ " \r\n" +
+ "";
+
+ projectContent = new DefaultProjectContent();
+ MockTextBuffer textBuffer = new MockTextBuffer(xml);
+
+ DefaultXmlFileExtensions extensions = new DefaultXmlFileExtensions(null);
+ XmlEditorOptions options = new XmlEditorOptions(new Properties());
+ parser = new XmlFoldParser(extensions, options);
+ unit = parser.Parse(projectContent, @"d:\projects\a.xml", textBuffer);
+ }
+
+ [Test]
+ public void FoldRegionCoversRootElement()
+ {
+ int beginLine = 1;
+ int endLine = 3;
+ int beginCol = 1;
+ int endCol = 8;
+ DomRegion expectedRegion = new DomRegion(beginLine, beginCol, endLine, endCol);
+
+ Assert.AreEqual(expectedRegion, unit.FoldingRegions[0].Region);
+ }
+
+ [Test]
+ public void CompilationUnitHasOneFoldRegion()
+ {
+ Assert.AreEqual(1, unit.FoldingRegions.Count);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/SingleRootElementFoldTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/SingleRootElementFoldTestFixture.cs
new file mode 100644
index 0000000000..3713f5d059
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/SingleRootElementFoldTestFixture.cs
@@ -0,0 +1,106 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.XmlEditor;
+using NUnit.Framework;
+using XmlEditor.Tests.Utils;
+
+namespace XmlEditor.Tests.Folding
+{
+ [TestFixture]
+ public class SingleRootElementFoldTestFixture
+ {
+ XmlFoldParser parser;
+ ICompilationUnit unit;
+ DefaultXmlFileExtensions extensions;
+ DefaultProjectContent projectContent;
+
+ [SetUp]
+ public void Init()
+ {
+ string xml =
+ "\r\n" +
+ "";
+
+ projectContent = new DefaultProjectContent();
+ MockTextBuffer textBuffer = new MockTextBuffer(xml);
+
+ extensions = new DefaultXmlFileExtensions(null);
+ extensions.Add(".wxs");
+ XmlEditorOptions options = new XmlEditorOptions(new Properties());
+ parser = new XmlFoldParser(extensions, options);
+ unit = parser.Parse(projectContent, @"d:\projects\a.xml", textBuffer);
+ }
+
+ [Test]
+ public void XmlFoldParserCanParseProjectReturnsTrue()
+ {
+ IProject project = null;
+ Assert.IsTrue(parser.CanParse(project));
+ }
+
+ [Test]
+ public void XmlFoldParserLexerTagsHasNoItems()
+ {
+ Assert.AreEqual(0, parser.LexerTags.Length);
+ }
+
+ [Test]
+ public void XmlFoldParserCanParseReturnsTrueIfFileExtensionInDefaultXmlFileExtensions()
+ {
+ Assert.IsTrue(parser.CanParse("TEST.WXS"));
+ }
+
+ [Test]
+ public void XmlFoldParserCanParseReturnsFalseForUnknownFileExtension()
+ {
+ Assert.IsFalse(parser.CanParse("test.unknown"));
+ }
+
+ [Test]
+ public void CompilationUnitUsesProjectContentPassedToParseMethod()
+ {
+ Assert.AreSame(projectContent, unit.ProjectContent);
+ }
+
+ [Test]
+ public void CompilationUnitFileNameIsFileNamePassedToParseMethod()
+ {
+ Assert.AreEqual(@"d:\projects\a.xml", unit.FileName);
+ }
+
+ [Test]
+ public void FoldingRegionsHasOneFold()
+ {
+ Assert.AreEqual(1, unit.FoldingRegions.Count);
+ }
+
+ [Test]
+ public void FoldNameIsElementNameSurroundedByAngledBrackets()
+ {
+ Assert.AreEqual("", unit.FoldingRegions[0].Name);
+ }
+
+ [Test]
+ public void FoldRegionContainsRootElement()
+ {
+ int beginLine = 1;
+ int beginColumn = 1;
+ int endLine = 2;
+ int endColumn = 8;
+ DomRegion expectedRegion = new DomRegion(beginLine, beginColumn, endLine, endColumn);
+ Assert.AreEqual(expectedRegion, unit.FoldingRegions[0].Region);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/TwoElementFoldsTestFixture.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/TwoElementFoldsTestFixture.cs
new file mode 100644
index 0000000000..0ae0c45d6a
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Folding/TwoElementFoldsTestFixture.cs
@@ -0,0 +1,70 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.Collections.Generic;
+
+using ICSharpCode.Core;
+using ICSharpCode.SharpDevelop;
+using ICSharpCode.SharpDevelop.Dom;
+using ICSharpCode.SharpDevelop.Project;
+using ICSharpCode.XmlEditor;
+using NUnit.Framework;
+using XmlEditor.Tests.Utils;
+
+namespace XmlEditor.Tests.Folding
+{
+ [TestFixture]
+ public class TwoElementFoldsTestFixture
+ {
+ XmlFoldParser parser;
+ ICompilationUnit unit;
+ DefaultProjectContent projectContent;
+
+ [SetUp]
+ public void Init()
+ {
+ string xml =
+ "\r\n" +
+ " \r\n" +
+ " \r\n" +
+ "";
+
+ projectContent = new DefaultProjectContent();
+ MockTextBuffer textBuffer = new MockTextBuffer(xml);
+
+ DefaultXmlFileExtensions extensions = new DefaultXmlFileExtensions(null);
+ XmlEditorOptions options = new XmlEditorOptions(new Properties());
+ parser = new XmlFoldParser(extensions, options);
+ unit = parser.Parse(projectContent, @"d:\projects\a.xml", textBuffer);
+ }
+
+ [Test]
+ public void FirstFoldRegionCoversRootElement()
+ {
+ int beginLine = 1;
+ int endLine = 4;
+ int beginCol = 1;
+ int endCol = 8;
+ DomRegion expectedRegion = new DomRegion(beginLine, beginCol, endLine, endCol);
+
+ Assert.AreEqual(expectedRegion, unit.FoldingRegions[0].Region);
+ }
+
+ [Test]
+ public void SecondFoldRegionCoversChildElement()
+ {
+ int beginLine = 2;
+ int endLine = 3;
+ int beginCol = 5;
+ int endCol = 13;
+ DomRegion expectedRegion = new DomRegion(beginLine, beginCol, endLine, endCol);
+
+ Assert.AreEqual(expectedRegion, unit.FoldingRegions[1].Region);
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockTextBuffer.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockTextBuffer.cs
new file mode 100644
index 0000000000..c7bbf3ae12
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/MockTextBuffer.cs
@@ -0,0 +1,73 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.IO;
+using ICSharpCode.SharpDevelop;
+
+namespace XmlEditor.Tests.Utils
+{
+ public class MockTextBuffer : ITextBuffer
+ {
+ string text = String.Empty;
+
+ public MockTextBuffer(string text)
+ {
+ this.text = text;
+ }
+
+ public event EventHandler TextChanged;
+
+ protected virtual void OnTextChanged(EventArgs e)
+ {
+ if (TextChanged != null) {
+ TextChanged(this, e);
+ }
+ }
+
+ public ITextBufferVersion Version {
+ get {
+ throw new NotImplementedException();
+ }
+ }
+
+ public int TextLength {
+ get {
+ throw new NotImplementedException();
+ }
+ }
+
+ public string Text {
+ get { return text; }
+ }
+
+ public ITextBuffer CreateSnapshot()
+ {
+ throw new NotImplementedException();
+ }
+
+ public ITextBuffer CreateSnapshot(int offset, int length)
+ {
+ throw new NotImplementedException();
+ }
+
+ public TextReader CreateReader()
+ {
+ return new StringReader(text);
+ }
+
+ public char GetCharAt(int offset)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string GetText(int offset, int length)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/Tests/MockTextBufferTests.cs b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/Tests/MockTextBufferTests.cs
new file mode 100644
index 0000000000..19577e4788
--- /dev/null
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/Utils/Tests/MockTextBufferTests.cs
@@ -0,0 +1,41 @@
+//
+//
+//
+//
+// $Revision$
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Xml;
+
+using NUnit.Framework;
+using XmlEditor.Tests.Utils;
+
+namespace XmlEditor.Tests.Utils.Tests
+{
+ [TestFixture]
+ public class MockTextBufferTests
+ {
+ [Test]
+ public void CanGetTextFromTextBufferTextProperty()
+ {
+ string expectedText = "abc";
+ MockTextBuffer textBuffer = new MockTextBuffer(expectedText);
+ Assert.AreEqual(expectedText, textBuffer.Text);
+ }
+
+ [Test]
+ public void CanGetTextFromReaderReturnedFromTextBufferCreateReader()
+ {
+ string expectedText = "abc";
+ MockTextBuffer textBuffer = new MockTextBuffer("abc");
+
+ StringBuilder text = new StringBuilder();
+ using (TextReader reader = textBuffer.CreateReader()) {
+ Assert.AreEqual(expectedText, reader.ReadToEnd());
+ }
+ }
+ }
+}
diff --git a/src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj b/src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj
index b7a0c8a8d9..be57718543 100644
--- a/src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj
+++ b/src/AddIns/DisplayBindings/XmlEditor/Test/XmlEditor.Tests.csproj
@@ -120,6 +120,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -206,6 +219,7 @@
+
@@ -218,6 +232,7 @@
+
@@ -276,6 +291,7 @@
+