review javadoc and exception messages for all DOM-related classes

Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/L1CommentHandlingTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/L1CommentHandlingTest.java
index fdeaa82..b7d6acc 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/L1CommentHandlingTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/L1CommentHandlingTest.java
@@ -17,7 +17,6 @@
 

 import java.util.List;

 

-import org.eclipse.core.runtime.AssertionFailedException;

 import org.eclipse.core.runtime.QualifiedName;

 import org.junit.Before;

 import org.junit.Test;

@@ -79,7 +78,7 @@
 		assertEquals("Hello World", comment.getText());

 	}

 

-	@Test(expected = AssertionFailedException.class)

+	@Test(expected = DocumentValidationException.class)

 	public void shouldNotInsertCommentAtInvalidInsertionPoint() throws Exception {

 		document.insertComment(rootElement.getStartOffset());

 	}

diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Attribute.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Attribute.java
index d8b13a8..4c26a5b 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Attribute.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Attribute.java
@@ -1,5 +1,5 @@
 /*******************************************************************************

- * Copyright (c) 2010 Florian Thienel and others.

+ * Copyright (c) 2010, 2013 Florian Thienel and others.

  * All rights reserved. This program and the accompanying materials

  * are made available under the terms of the Eclipse Public License v1.0

  * which accompanies this distribution, and is available at

@@ -13,8 +13,8 @@
 import org.eclipse.core.runtime.QualifiedName;

 

 /**

- * An immutable representation of an attribute within the start tag of an element. The attribute is Comparable by its

- * qualified name.

+ * An immutable representation of an attribute within the start tag of an element. An attribute consists of a qualified

+ * name and a value. It is Comparable by its qualified name, which is the natural order of attributes.

  * 

  * @author Florian Thienel

  */

@@ -26,10 +26,31 @@
 

 	private final String value;

 

+	/**

+	 * Create an attribute within the namespace of the parent element, i.e. only the local name without a qualifier is

+	 * given.

+	 * 

+	 * @param parent

+	 *            the element containing the attribute

+	 * @param localName

+	 *            the local name of the attribute

+	 * @param value

+	 *            the value of the attribute

+	 */

 	public Attribute(final Element parent, final String localName, final String value) {

 		this(parent, new QualifiedName(null, localName), value);

 	}

 

+	/**

+	 * Create an attribute within an arbitrary namespace.

+	 * 

+	 * @param parent

+	 *            the element containing the attribute

+	 * @param name

+	 *            the qualified name of the attribute

+	 * @param value

+	 *            the value of the attribute

+	 */

 	public Attribute(final Element parent, final QualifiedName name, final String value) {

 		this.parent = parent;

 		this.name = name;

@@ -48,9 +69,6 @@
 		return value;

 	}

 

-	/**

-	 * @return a pair of the namespace URI and the local name

-	 */

 	public QualifiedName getQualifiedName() {

 		return name;

 	}

@@ -73,7 +91,7 @@
 	}

 

 	/**

-	 * Compares two attributes by their name.

+	 * Compares two attributes by their qualified name.

 	 * 

 	 * @param otherAttribute

 	 *            the other attribute

diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Comment.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Comment.java
index d0f05e8..cf196d9 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Comment.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Comment.java
@@ -11,6 +11,8 @@
 package org.eclipse.vex.core.internal.dom;

 

 /**

+ * A representation of an XML comment in the DOM. Comments have textual content, a start and an end tag.

+ * 

  * @author Florian Thienel

  */

 public class Comment extends Node {

@@ -26,6 +28,14 @@
 	}

 

 	@Override

+	public boolean isKindOf(final Node node) {

+		if (!(node instanceof Comment)) {

+			return false;

+		}

+		return true;

+	}

+

+	@Override

 	public String toString() {

 		final StringBuffer sb = new StringBuffer();

 

diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Content.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Content.java
index 152d013..7afa887 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Content.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Content.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay and others.
+ * Copyright (c) 2004, 2013 John Krasnay and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,28 +7,26 @@
  * 
  * Contributors:
  *     John Krasnay - initial API and implementation
+ *     Florian Thienel - refactoring to full fledged DOM
  *******************************************************************************/
 package org.eclipse.vex.core.internal.dom;
 
 /**
- * Interface for classes that manage a string of characters representing the content of a document.
- * 
- * @model
+ * Interface for classes that manage a string of characters representing the textual content of a document.
  */
 public interface Content extends CharSequence {
 
 	/**
-	 * Creates a new Position object at the given initial offset.
+	 * Create a new Position object at the given initial offset.
 	 * 
 	 * @param offset
 	 *            initial offset of the position
-	 * @model
 	 */
 	public Position createPosition(int offset);
 
 	/**
-	 * Removes the given Position from the list of positions. A removed position is not updated anymore when this
-	 * content is modified.
+	 * Remove the given Position from the list of positions. A removed position is not updated anymore when this content
+	 * is modified.
 	 * 
 	 * @param position
 	 *            the position to remove
@@ -36,15 +34,14 @@
 	public void removePosition(Position position);
 
 	/**
-	 * Insert a string into the content.
+	 * Insert given text into the content.
 	 * 
 	 * @param offset
 	 *            Offset at which to insert the string.
-	 * @param s
-	 *            String to insert.
-	 * @model
+	 * @param text
+	 *            Text to insert.
 	 */
-	public void insertText(int offset, String s);
+	public void insertText(int offset, String text);
 
 	/**
 	 * Get the plain text of a region of this content. The plain text does not contain any information about the element
@@ -87,7 +84,7 @@
 	public String getRawText();
 
 	/**
-	 * Inserts the given content into this content at the given offset.
+	 * Insert the given content into this content at the given offset.
 	 * 
 	 * @param offset
 	 *            Offset at which to insert the given content
@@ -119,34 +116,29 @@
 	 * 
 	 * @param offset
 	 *            Offset at which to insert the element marker.
-	 * @model
 	 */
 	public void insertElementMarker(int offset);
 
 	/**
-	 * Indicates if the character at the given offset is an element marker.
+	 * Indicate if the character at the given offset is an element marker.
 	 * 
 	 * @param offset
 	 *            Offset at which to check if an element marker is present.
-	 * @model
 	 */
 	public boolean isElementMarker(int offset);
 
 	/**
-	 * Deletes the given range of characters.
+	 * Delete the given range of characters.
 	 * 
 	 * @param offset
 	 *            Offset from which characters should be deleted.
 	 * @param length
 	 *            Number of characters to delete.
-	 * @model
 	 */
 	public void remove(ContentRange range);
 
 	/**
-	 * Return the length of the content.
-	 * 
-	 * @model
+	 * @return the length of the content.
 	 */
 	public int length();
 
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/ContentRange.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/ContentRange.java
index 79bc33a..e011041 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/ContentRange.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/ContentRange.java
@@ -15,6 +15,9 @@
 import org.eclipse.core.runtime.Assert;

 

 /**

+ * An immutable representation of a range within Content.

+ * 

+ * @see Content

  * @author Florian Thienel

  */

 public class ContentRange {

@@ -22,6 +25,12 @@
 	private final int startOffset;

 	private final int endOffset;

 

+	/**

+	 * @param startOffset

+	 *            the start offset of this range

+	 * @param endOffset

+	 *            the end offset of this range

+	 */

 	public ContentRange(final int startOffset, final int endOffset) {

 		Assert.isTrue(startOffset <= endOffset, MessageFormat.format("startOffset {0} must not be greater than endOffset {1}", startOffset, endOffset));

 		this.startOffset = startOffset;

@@ -36,34 +45,73 @@
 		return endOffset;

 	}

 

+	/**

+	 * The length is always >= 1, since a range includes all characters from its start offset to its end offset.

+	 * 

+	 * @return the length of this range

+	 */

 	public int length() {

 		return endOffset - startOffset + 1;

 	}

 

+	/**

+	 * Indicate whether this range contains the given range.

+	 * 

+	 * @return true if this range contains the given range

+	 */

 	public boolean contains(final ContentRange other) {

 		return startOffset <= other.startOffset && endOffset >= other.endOffset;

 	}

 

+	/**

+	 * Indicate whether this range contains the given offset.

+	 * 

+	 * @return true if this range contains the given offset

+	 */

 	public boolean contains(final int offset) {

 		return startOffset <= offset && offset <= endOffset;

 	}

 

+	/**

+	 * Indicate whether this range intersects with the given range. Intersection is weaker than containment: one range

+	 * may contain only a part of the other range.

+	 * 

+	 * @return true if this range intersects with the given range

+	 */

 	public boolean intersects(final ContentRange other) {

 		return startOffset <= other.endOffset && endOffset >= other.startOffset;

 	}

 

+	/**

+	 * @return the intersection of this and the given range

+	 */

 	public ContentRange intersection(final ContentRange other) {

 		return new ContentRange(Math.max(other.getStartOffset(), startOffset), Math.min(endOffset, other.getEndOffset()));

 	}

 

+	/**

+	 * The union of this and the given range may also include characters between both ranges, if they do not intersect.

+	 * 

+	 * @return the union of this and the given range

+	 */

 	public ContentRange union(final ContentRange other) {

 		return new ContentRange(Math.min(startOffset, other.startOffset), Math.min(endOffset, other.endOffset));

 	}

 

-	public ContentRange moveBy(final int delta) {

-		return resizeBy(delta, delta);

+	/**

+	 * Move this range by the given distance. Since ContentRange is immutable, a new moved range is returned.

+	 * 

+	 * @return the moved range

+	 */

+	public ContentRange moveBy(final int distance) {

+		return resizeBy(distance, distance);

 	}

 

+	/**

+	 * Resize this range by the given delta. Since ContentRange is immutable, a new resized range is returned.

+	 * 

+	 * @return the resized range

+	 */

 	public ContentRange resizeBy(final int deltaStart, final int deltaEnd) {

 		return new ContentRange(startOffset + deltaStart, endOffset + deltaEnd);

 	}

diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/CopyOfElement.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/CopyOfElement.java
index 97e722c..37a1e9d 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/CopyOfElement.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/CopyOfElement.java
@@ -11,12 +11,22 @@
 package org.eclipse.vex.core.internal.dom;

 

 /**

+ * This visitor copies the properties of a source element into the visited elements:

+ * <ul>

+ * <li>attributes</li>

+ * <li>namespace declarations</li>

+ * </ul>

+ * 

  * @author Florian Thienel

  */

 public class CopyOfElement extends BaseNodeVisitor {

 

 	private final Element source;

 

+	/**

+	 * @param source

+	 *            the source element

+	 */

 	public CopyOfElement(final Element source) {

 		this.source = source;

 	}

diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Document.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Document.java
index 94d2055..33e8646 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Document.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Document.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay and others.
+ * Copyright (c) 2004, 2013 John Krasnay and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
  * Contributors:
  *     John Krasnay - initial API and implementation
  *     Igor Jacy Lino Campista - Java 5 warnings fixed (bug 311325)
+ *     Florian Thienel - refactoring to full fledged DOM
  *******************************************************************************/
 package org.eclipse.vex.core.internal.dom;
 
@@ -21,7 +22,7 @@
 import org.eclipse.vex.core.internal.core.ListenerList;
 
 /**
- * Represents an XML document.
+ * A representation of an XML document in the DOM.
  */
 public class Document extends Parent {
 
@@ -36,7 +37,8 @@
 	private Validator validator;
 
 	/**
-	 * Class constructor.
+	 * Create a new document with the given root element. This constructor creates a Content object and associates both
+	 * the root element and the document with it.
 	 * 
 	 * @param rootElement
 	 *            root element of the document. The document property of this RootElement is set by this constructor.
@@ -54,8 +56,8 @@
 	}
 
 	/**
-	 * Class constructor. This constructor is used by the document builder and assumes that the content and root element
-	 * have bee properly set up and is already associated with the given content.
+	 * Create a new document with the given content and root element. This constructor assumes that the content and root
+	 * element have bee properly set up and are already associated. It associates the document with the given content.
 	 * 
 	 * @param content
 	 *            Content object used to store the document's content.
@@ -147,14 +149,33 @@
 		return rootElement;
 	}
 
+	/**
+	 * @return the length of the textual content of this document plus 1 for each opening or closing XML tag (element
+	 *         tags, comment tags, PI tags and entity references).
+	 */
 	public int getLength() {
 		return getContent().length();
 	}
 
+	/**
+	 * Create a Position for the given offset. A position is automatically updated if it "moves" due to content
+	 * modifications.
+	 * 
+	 * <p>
+	 * All created positions are referenced by this document. <b>Make sure to remove positions you don't need
+	 * anymore.</b>
+	 * 
+	 * @see Position
+	 * @see Document#removePosition(Position)
+	 * @return the Position for the given offset
+	 */
 	public Position createPosition(final int offset) {
 		return getContent().createPosition(offset);
 	}
 
+	/**
+	 * Remove the given Position. A removed position is not updated anymore.
+	 */
 	public void removePosition(final Position position) {
 		getContent().removePosition(position);
 	}
@@ -197,10 +218,23 @@
 		});
 	}
 
+	/**
+	 * @return true if text can be inserted at the given offset
+	 */
 	public boolean canInsertText(final int offset) {
 		return canInsertAt(getNodeForInsertionAt(offset), offset, Validator.PCDATA);
 	}
 
+	/**
+	 * Insert the given text at the given offset.
+	 * 
+	 * @param offset
+	 *            the offset at which the text should be inserted
+	 * @param text
+	 *            The text to insert. Control characters are automatically converted to \s (except for \n).
+	 * @throws DocumentValidationException
+	 *             if text is not allowed at the given offset
+	 */
 	public void insertText(final int offset, final String text) throws DocumentValidationException {
 		Assert.isTrue(offset > getStartOffset() && offset <= getEndOffset(), MessageFormat.format("Offset must be in [{0}, {1}]", getStartOffset() + 1, getEndOffset()));
 
@@ -249,6 +283,9 @@
 		return new String(characters);
 	}
 
+	/**
+	 * @return true if a comment can be inserted a the given offset
+	 */
 	public boolean canInsertComment(final int offset) {
 		// TODO Currently comments can only be inserted within the root element.
 		if (!(offset > rootElement.getStartOffset() && offset <= rootElement.getEndOffset())) {
@@ -261,8 +298,20 @@
 		return true;
 	}
 
-	public Comment insertComment(final int offset) {
-		Assert.isTrue(canInsertComment(offset));
+	/**
+	 * Insert a new comment at the given offset.
+	 * 
+	 * @see Comment
+	 * @param offset
+	 *            the offset at which the comment should be inserted
+	 * @return the new comment
+	 * @throws DocumentValidationException
+	 *             if a comment is not allowed a the given offset (e.g. within an existing comment)
+	 */
+	public Comment insertComment(final int offset) throws DocumentValidationException {
+		if (!canInsertComment(offset)) {
+			throw new DocumentValidationException(MessageFormat.format("Cannot insert a comment at offset {0}.", offset));
+		}
 
 		final Element parent = getElementForInsertionAt(offset);
 
@@ -280,10 +329,26 @@
 		return comment;
 	}
 
+	/**
+	 * @return true if a new element with the given qualified name can be inserted at the given offset
+	 */
 	public boolean canInsertElement(final int offset, final QualifiedName elementName) {
 		return canInsertAt(getElementForInsertionAt(offset), offset, elementName);
 	}
 
+	/**
+	 * Insert a new element with the given qualified name a the given offset.
+	 * 
+	 * @see Element
+	 * @see QualifiedName
+	 * @param offset
+	 *            the offset at which the element should be inserted
+	 * @param elementName
+	 *            the qualified name of the new element
+	 * @return the new element
+	 * @throws DocumentValidationException
+	 *             if an element with the given qualified name is not allowed a the given offset
+	 */
 	public Element insertElement(final int offset, final QualifiedName elementName) throws DocumentValidationException {
 		Assert.isTrue(offset > rootElement.getStartOffset() && offset <= rootElement.getEndOffset(), MessageFormat.format("Offset must be in [{0}, {1}]", getStartOffset() + 1, getEndOffset()));
 
@@ -306,18 +371,30 @@
 		return element;
 	}
 
+	/**
+	 * @return true if the given DocumentFragment can be inserted at the given offset
+	 */
 	public boolean canInsertFragment(final int offset, final DocumentFragment fragment) {
 		return canInsertAt(getElementForInsertionAt(offset), offset, fragment.getNodeNames());
 	}
 
+	/**
+	 * Insert the given DocumentFragment at the given offset.
+	 * 
+	 * @see DocumentFragment
+	 * @param offset
+	 *            the offset at which the fragment should be inserted
+	 * @param fragment
+	 *            the fragment to insert
+	 * @throws DocumentValidationException
+	 *             if the given fragment may not be inserted at the given offset
+	 */
 	public void insertFragment(final int offset, final DocumentFragment fragment) throws DocumentValidationException {
-		if (offset < 1 || offset >= getLength()) {
-			throw new IllegalArgumentException("Error inserting document fragment");
-		}
+		Assert.isTrue(isInsertionPointIn(this, offset), "Cannot insert fragment outside of the document range.");
 
 		final Element parent = getElementForInsertionAt(offset);
 		if (!canInsertAt(parent, offset, fragment.getNodeNames())) {
-			throw new DocumentValidationException("Cannot insert document fragment");
+			throw new DocumentValidationException(MessageFormat.format("Cannot insert document fragment at offset {0}.", offset));
 		}
 
 		fireBeforeContentInserted(new DocumentEvent(this, parent, offset, 2, null));
@@ -336,12 +413,18 @@
 		fireContentInserted(new DocumentEvent(this, parent, offset, fragment.getContent().length(), null));
 	}
 
+	/**
+	 * Delete everything in the given range. The range must be balanced i.e. it must start in the same node as it ends.
+	 * 
+	 * @param range
+	 *            the range to delete
+	 * @throws DocumentValidationException
+	 *             if the deletion would lead to an invalid document
+	 */
 	public void delete(final ContentRange range) throws DocumentValidationException {
 		final Parent surroundingParent = getParentAt(range.getStartOffset());
 		final Parent parentAtEndOffset = getParentAt(range.getEndOffset());
-		if (surroundingParent != parentAtEndOffset) {
-			throw new IllegalArgumentException("Deletion in " + range + " is unbalanced");
-		}
+		Assert.isTrue(surroundingParent == parentAtEndOffset, MessageFormat.format("Range {0} for deletion is unbalanced: {1} -> {2}", range, surroundingParent, parentAtEndOffset));
 
 		final Parent parentForDeletion;
 		if (range.equals(surroundingParent.getRange())) {
@@ -386,6 +469,9 @@
 	 * Miscellaneous
 	 */
 
+	/**
+	 * @return the character at the given offset. If there is an XML tag at the given offset \0 is returned.
+	 */
 	public char getCharacterAt(final int offset) {
 		final String text = getContent().getText(new ContentRange(offset, offset));
 		if (text.length() == 0) {
@@ -399,6 +485,15 @@
 		return text.charAt(0);
 	}
 
+	/**
+	 * Find the nearest common node of the given offsets going from each offset to the root element.
+	 * 
+	 * @param offset1
+	 *            the first offset
+	 * @param offset2
+	 *            the second offset
+	 * @return the nearest common node for both offsets
+	 */
 	public Node findCommonNode(final int offset1, final int offset2) {
 		Assert.isTrue(containsOffset(offset1) && containsOffset(offset2));
 		return findCommonNodeIn(this, offset1, offset2);
@@ -424,10 +519,16 @@
 		return isInsertionPointIn(node, offset1) && isInsertionPointIn(node, offset2);
 	}
 
+	/**
+	 * @return true if the given node would contain an insertion at the given offset
+	 */
 	public static boolean isInsertionPointIn(final Node node, final int offset) {
 		return node.getRange().resizeBy(1, 0).contains(offset);
 	}
 
+	/**
+	 * @return the node in which an insertion at the given offset will end
+	 */
 	public Node getNodeForInsertionAt(final int offset) {
 		final Node node = getChildNodeAt(offset);
 		if (node instanceof Text) {
@@ -439,6 +540,9 @@
 		return node;
 	}
 
+	/**
+	 * @return the element in which an insertion at the given offset will end
+	 */
 	public Element getElementForInsertionAt(final int offset) {
 		final Element parent = getParentElement(getChildNodeAt(offset));
 		if (offset == parent.getStartOffset()) {
@@ -465,10 +569,23 @@
 		return child.getParent();
 	}
 
+	/**
+	 * @return true if there is an XML tag at the given offset (element tags, comment tags, PI tags and entity
+	 *         references)
+	 */
 	public boolean isElementAt(final int offset) {
 		return getContent().isElementMarker(offset);
 	}
 
+	/**
+	 * Create a new DocumentFragment with a deep copy of the given range in this document. The range must be balanced
+	 * i.e. it must start in the same node as it ends.
+	 * 
+	 * @see DocumentFragment
+	 * @param range
+	 *            the range to copy into the fragment
+	 * @return a new fragment with a deep copy of the given range
+	 */
 	public DocumentFragment getFragment(final ContentRange range) {
 		final Parent parent = getParentOfRange(range);
 		final DeepCopy deepCopy = new DeepCopy(parent, range);
@@ -487,6 +604,9 @@
 		return parent;
 	}
 
+	/**
+	 * @return all nodes in the given range in this document
+	 */
 	public List<Node> getNodes(final ContentRange range) {
 		return getParentOfRange(range).getChildNodes(range);
 	}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/DocumentEvent.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/DocumentEvent.java
index 8c57ba3..eaa7118 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/DocumentEvent.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/DocumentEvent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay and others.
+ * Copyright (c) 2004, 2013 John Krasnay and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  * 
  * Contributors:
  *     John Krasnay - initial API and implementation
+ *     Florian Thienel - support for attribute changes
  *******************************************************************************/
 package org.eclipse.vex.core.internal.dom;
 
@@ -17,8 +18,6 @@
 
 /**
  * Encapsulation of the details of a document change
- * 
- * @model
  */
 public class DocumentEvent extends EventObject {
 
@@ -48,7 +47,6 @@
 	 *            IUndoableEdit that can be used to undo the change.
 	 */
 	public DocumentEvent(final Document document, final Parent parent, final int offset, final int length, final IUndoableEdit undoableEdit) {
-
 		super(document);
 		this.document = document;
 		this.parent = parent;
@@ -75,7 +73,6 @@
 	 */
 	public DocumentEvent(final Document document, final Parent parent, final QualifiedName attributeName, final String oldAttributeValue, final String newAttributeValue,
 			final IUndoableEdit undoableEdit) {
-
 		super(document);
 		this.document = document;
 		this.parent = parent;
@@ -86,33 +83,28 @@
 	}
 
 	/**
-	 * Returns the length of the change.
-	 * 
-	 * @model
+	 * @return the length of the change
 	 */
 	public int getLength() {
 		return length;
 	}
 
 	/**
-	 * Returns the offset at which the change occurred.
-	 * 
-	 * @model
+	 * @return the offset at which the change occurred
 	 */
 	public int getOffset() {
 		return offset;
 	}
 
 	/**
-	 * @return the Parent containing the change.
+	 * @return the Parent containing the change
 	 */
 	public Parent getParent() {
 		return parent;
 	}
 
 	/**
-	 * @return the value of the attribute before the change. If null, indicates that the attribute was removed.
-	 * @model
+	 * @return the value of the attribute before the change. If null, indicates that the attribute was removed
 	 */
 	public String getNewAttributeValue() {
 		return newAttributeValue;
@@ -120,16 +112,14 @@
 
 	/**
 	 * @return the value of the attribute after the change. If null, indicates the attribute did not exist before the
-	 *         change.
-	 * @model
+	 *         change
 	 */
 	public String getOldAttributeValue() {
 		return oldAttributeValue;
 	}
 
 	/**
-	 * @return the name of the attribute that was changed.
-	 * @model
+	 * @return the qualified name of the attribute that was changed
 	 */
 	public QualifiedName getAttributeName() {
 		return attributeName;
@@ -137,17 +127,14 @@
 
 	/**
 	 * @return the document for which this event was generated
-	 * @model
 	 */
 	public Document getDocument() {
 		return document;
 	}
 
 	/**
-	 * Returns the undoable edit that can be used to undo the action. May be null, in which case the action cannot be
-	 * undone.
-	 * 
-	 * @model
+	 * @return the undoable edit that can be used to undo the action. May be null, in which case the action cannot be
+	 *         undone.
 	 */
 	public IUndoableEdit getUndoableEdit() {
 		return undoableEdit;
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/DocumentFragment.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/DocumentFragment.java
index 4095368..1acfc5d 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/DocumentFragment.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/DocumentFragment.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay and others.
+ * Copyright (c) 2004, 2013 John Krasnay and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -8,25 +8,27 @@
  * Contributors:
  *     John Krasnay - initial API and implementation
  *     Igor Jacy Lino Campista - Java 5 warnings fixed (bug 311325)
+ *     Florian Thienel - extracted responsibility for serialization, refactoring to full fledged DOM  
  *******************************************************************************/
 package org.eclipse.vex.core.internal.dom;
 
-import java.util.ArrayList;
 import java.util.List;
 
 import org.eclipse.core.runtime.Assert;
 import org.eclipse.core.runtime.QualifiedName;
 
 /**
- * Represents a fragment of an XML document.
+ * Represents a wellformed fragment of an XML document.
  */
 public class DocumentFragment extends Parent {
 
 	/**
+	 * Create a new fragment with based on the given content and nodes.
+	 * 
 	 * @param content
-	 *            Content holding the fragment's content.
+	 *            the Content holding the fragment's content
 	 * @param nodes
-	 *            Elements that make up this fragment.
+	 *            the nodes that make up the structure of this fragment
 	 */
 	public DocumentFragment(final Content content, final List<Node> nodes) {
 		Assert.isTrue(content.length() > 0);
@@ -36,31 +38,34 @@
 		}
 	}
 
+	/**
+	 * @return the length of the textual content of this fragment plus 1 for each opening or closing XML tag (element
+	 *         tags, comment tags, PI tags and entity references)
+	 */
 	public int getLength() {
 		return getContent().length();
 	}
 
-	public List<Element> getElements() {
-		final List<Element> elements = new ArrayList<Element>();
-		for (final Node node : getNodes()) {
-			node.accept(new BaseNodeVisitor() {
-				@Override
-				public void visit(final Element element) {
-					elements.add(element);
-				}
-			});
-		}
-		return elements;
-	}
-
+	/**
+	 * @return a list with the qualified names off all nodes on the root level of this fragment
+	 */
 	public List<QualifiedName> getNodeNames() {
 		return Node.getNodeNames(getChildNodes());
 	}
 
+	/**
+	 * @return all nodes on the root level of this fragment
+	 */
 	public List<Node> getNodes() {
 		return getChildNodes();
 	}
 
+	/**
+	 * The base URI of a fragment is always null because a fragment has no persistent representation.
+	 * 
+	 * @see Node#getBaseURI()
+	 * @return null
+	 */
 	@Override
 	public String getBaseURI() {
 		return null;
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/DocumentValidationException.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/DocumentValidationException.java
index 89a3c46..2324331 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/DocumentValidationException.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/DocumentValidationException.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay and others.
+ * Copyright (c) 2004, 2013 John Krasnay and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -18,10 +18,10 @@
 	private static final long serialVersionUID = 1L;
 
 	/**
-	 * Class constructor.
+	 * Create a new exception with the given message.
 	 * 
 	 * @param message
-	 *            Message indicating the nature of the exception.
+	 *            message indicating the nature of the exception
 	 */
 	public DocumentValidationException(final String message) {
 		super(message);
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Element.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Element.java
index 119c1eb..deb0fc2 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Element.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Element.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay and others.
+ * Copyright (c) 2004, 2013 John Krasnay and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
  * Contributors:
  *     John Krasnay - initial API and implementation
  *     Igor Jacy Lino Campista - Java 5 warnings fixed (bug 311325)
+ *     Florian Thienel - namespace handling (bug 253753), refactoring to full fledged DOM
  *******************************************************************************/
 package org.eclipse.vex.core.internal.dom;
 
@@ -24,7 +25,8 @@
 import org.eclipse.vex.core.internal.core.QualifiedNameComparator;
 
 /**
- * Represents a tag in an XML document. Methods are available for managing the element's attributes and children.
+ * A representation of an XML element in the DOM. Elements have attributes, namespace declarations and children, as well
+ * as a start and an end tag. The textual content of an element is represented by its child Text nodes.
  */
 public class Element extends Parent {
 
@@ -41,10 +43,23 @@
 	private final Map<QualifiedName, Attribute> attributes = new HashMap<QualifiedName, Attribute>();
 	private final Map<String, String> namespaceDeclarations = new HashMap<String, String>();
 
+	/**
+	 * Create an element with the given name in the default namespace (only the local name without the qualifier is
+	 * given).
+	 * 
+	 * @param localName
+	 *            the local name of the element
+	 */
 	public Element(final String localName) {
 		this(new QualifiedName(null, localName));
 	}
 
+	/**
+	 * Create an element with the given qualified name.
+	 * 
+	 * @param qualifiedName
+	 *            the qualified name of the element
+	 */
 	public Element(final QualifiedName qualifiedName) {
 		name = qualifiedName;
 	}
@@ -62,16 +77,29 @@
 		return super.getBaseURI();
 	}
 
+	/**
+	 * Set the base URI of this element. The xml:base attribute re-defines the base URI for a part of an XML document,
+	 * according to the XML Base Recommendation.
+	 * 
+	 * @see http://www.w3.org/TR/xmlbase/
+	 */
 	public void setBaseURI(final String baseURI) {
 		setAttribute(XML_BASE_ATTRIBUTE, baseURI);
 	}
 
+	/**
+	 * This element is the same kind as the given node if the node is also an element and both have the same qualified
+	 * name.
+	 * 
+	 * @see Node#isKindOf(Node)
+	 * @return true if this element and the given node are of the same kind
+	 */
 	@Override
-	public boolean isKindOf(final Node node) {
-		if (!(node instanceof Element)) {
+	public boolean isKindOf(final Node other) {
+		if (!(other instanceof Element)) {
 			return false;
 		}
-		return getQualifiedName().equals(((Element) node).getQualifiedName());
+		return getQualifiedName().equals(((Element) other).getQualifiedName());
 	}
 
 	@Override
@@ -96,10 +124,17 @@
 		return name.getLocalName();
 	}
 
+	/**
+	 * @return the declared namespace prefix for this element
+	 */
 	public String getPrefix() {
 		return getNamespacePrefix(name.getQualifier());
 	}
 
+	/**
+	 * @return the declared namespace prefix and the local name of this element separated by a colon (e.g.
+	 *         "prefix:localName")
+	 */
 	public String getPrefixedName() {
 		final String prefix = getPrefix();
 		if (prefix == null) {
@@ -108,6 +143,13 @@
 		return prefix + ":" + getLocalName();
 	}
 
+	/**
+	 * Qualify the given local name with the namespace qualifier of this element.
+	 * 
+	 * @param localName
+	 *            the local name to be qualified
+	 * @return the qualified variant of the given local name
+	 */
 	public QualifiedName qualify(final String localName) {
 		return new QualifiedName(name.getQualifier(), localName);
 	}
@@ -116,10 +158,16 @@
 	 * Attributes
 	 */
 
+	/**
+	 * @return the attribute with the given local name, or null if the attribute is not set
+	 */
 	public Attribute getAttribute(final String localName) {
 		return getAttribute(qualify(localName));
 	}
 
+	/**
+	 * @return the attribute with the given qualified name, or null if the attribute is not set
+	 */
 	public Attribute getAttribute(final QualifiedName name) {
 		return attributes.get(name);
 	}
@@ -128,6 +176,9 @@
 		return getAttributeValue(qualify(localName));
 	}
 
+	/**
+	 * @return the value of the attribute with the given qualified name, or null if the attribute is not set
+	 */
 	public String getAttributeValue(final QualifiedName name) {
 		final Attribute attribute = getAttribute(name);
 		if (attribute == null || "".equals(attribute.getValue().trim())) {
@@ -136,10 +187,26 @@
 		return attribute.getValue();
 	}
 
+	/**
+	 * Remove the attribute with the given local name.
+	 * 
+	 * @param localName
+	 *            the local name of the attribute to be removed
+	 * @throws DocumentValidationException
+	 *             if the removal of the attribute would make the document invalid
+	 */
 	public void removeAttribute(final String localName) throws DocumentValidationException {
 		removeAttribute(qualify(localName));
 	}
 
+	/**
+	 * Remove the attribute with the given qualified name.
+	 * 
+	 * @param name
+	 *            the qualified name of the attribute to be removed
+	 * @throws DocumentValidationException
+	 *             if the removal of the attribute would make the document invalid
+	 */
 	public void removeAttribute(final QualifiedName name) throws DocumentValidationException {
 		final Attribute attribute = this.getAttribute(name);
 		if (attribute == null) {
@@ -159,10 +226,30 @@
 		document.fireAttributeChanged(new DocumentEvent(document, this, name, oldValue, newValue, null));
 	}
 
-	public void setAttribute(final String name, final String value) throws DocumentValidationException {
-		setAttribute(qualify(name), value);
+	/**
+	 * Set the attribute with the given local name to the given value.
+	 * 
+	 * @param localName
+	 *            the local name of the attribute
+	 * @param value
+	 *            the new attribute value
+	 * @throws DocumentValidationException
+	 *             if the new attribute value would make the document invalid
+	 */
+	public void setAttribute(final String localName, final String value) throws DocumentValidationException {
+		setAttribute(qualify(localName), value);
 	}
 
+	/**
+	 * Set the attribute with the given qualified name to the given value.
+	 * 
+	 * @param name
+	 *            the qualified name of the attribute
+	 * @param value
+	 *            the new attribute value
+	 * @throws DocumentValidationException
+	 *             if the new attribute value would make the document invalid
+	 */
 	public void setAttribute(final QualifiedName name, final String value) throws DocumentValidationException {
 		final Attribute oldAttribute = attributes.get(name);
 		final String oldValue = oldAttribute != null ? oldAttribute.getValue() : null;
@@ -190,12 +277,18 @@
 		}
 	}
 
+	/**
+	 * @return all attributes currently set on this element
+	 */
 	public Collection<Attribute> getAttributes() {
 		final ArrayList<Attribute> result = new ArrayList<Attribute>(attributes.values());
 		Collections.sort(result);
 		return Collections.unmodifiableCollection(result);
 	}
 
+	/**
+	 * @return the qualified names of all attributes currently set on this element
+	 */
 	public List<QualifiedName> getAttributeNames() {
 		final ArrayList<QualifiedName> result = new ArrayList<QualifiedName>();
 		for (final Attribute attribute : attributes.values()) {
@@ -209,6 +302,9 @@
 	 * Element Structure
 	 */
 
+	/**
+	 * @return the parent element of this element
+	 */
 	public Element getParentElement() {
 		return getParentElement(this);
 	}
@@ -224,6 +320,9 @@
 		return getParentElement(parent);
 	}
 
+	/**
+	 * @return the child elements of this element
+	 */
 	public List<Element> getChildElements() {
 		final List<Node> nodes = getChildNodes();
 		final List<Element> elements = new ArrayList<Element>();
@@ -242,6 +341,10 @@
 	 * Namespaces
 	 */
 
+	/**
+	 * @return the namespace URI of the given namespace prefix, or null if no namespace with the given prefix is
+	 *         declared
+	 */
 	public String getNamespaceURI(final String namespacePrefix) {
 		if (namespaceDeclarations.containsKey(namespacePrefix)) {
 			return namespaceDeclarations.get(namespacePrefix);
@@ -253,14 +356,25 @@
 		return null;
 	}
 
+	/**
+	 * @return the default namespace URI or null, if no default namespace is declared
+	 */
 	public String getDefaultNamespaceURI() {
 		return getNamespaceURI(null);
 	}
 
+	/**
+	 * @return the URI of the default namespace declared on this element, or null if no default namespace is declared on
+	 *         this element
+	 */
 	public String getDeclaredDefaultNamespaceURI() {
 		return namespaceDeclarations.get(null);
 	}
 
+	/**
+	 * @return the declared namespace prefix for the given namespace URI, or null if the namespace with the given URI is
+	 *         not declared in the document
+	 */
 	public String getNamespacePrefix(final String namespaceURI) {
 		if (namespaceURI == null) {
 			return null;
@@ -286,6 +400,9 @@
 		return null;
 	}
 
+	/**
+	 * @return the prefixes of the namespaces that are declared on this element
+	 */
 	public Collection<String> getDeclaredNamespacePrefixes() {
 		final ArrayList<String> result = new ArrayList<String>();
 		for (final String prefix : namespaceDeclarations.keySet()) {
@@ -297,6 +414,9 @@
 		return result;
 	}
 
+	/**
+	 * @return the prefixes of the declared namespaces
+	 */
 	public Collection<String> getNamespacePrefixes() {
 		final HashSet<String> result = new HashSet<String>();
 		result.addAll(getDeclaredNamespacePrefixes());
@@ -307,6 +427,14 @@
 		return result;
 	}
 
+	/**
+	 * Declare a namespace with the given prefix and URI on this element.
+	 * 
+	 * @param namespacePrefix
+	 *            the prefix of the namespace to be declared
+	 * @param namespaceURI
+	 *            the URI of the namespace to be declared
+	 */
 	public void declareNamespace(final String namespacePrefix, final String namespaceURI) {
 		if (namespaceURI == null || "".equals(namespaceURI.trim())) {
 			return;
@@ -324,6 +452,12 @@
 		document.fireNamespaceChanged(new DocumentEvent(document, this, getStartOffset(), 0, null));
 	}
 
+	/**
+	 * Remove the namespace declaration with the given prefix from this element.
+	 * 
+	 * @param namespacePrefix
+	 *            the prefix of the namespace to be removed
+	 */
 	public void removeNamespace(final String namespacePrefix) {
 		final String oldNamespaceURI = namespaceDeclarations.remove(namespacePrefix);
 		final Document document = getDocument();
@@ -338,10 +472,19 @@
 		document.fireNamespaceChanged(new DocumentEvent(document, this, getStartOffset(), 0, null));
 	}
 
+	/**
+	 * Declare the default namespace with the given URI on this element.
+	 * 
+	 * @param namespaceURI
+	 *            the URI of the default namespace
+	 */
 	public void declareDefaultNamespace(final String namespaceURI) {
 		declareNamespace(null, namespaceURI);
 	}
 
+	/**
+	 * Remove the declaration of the default namespace from this element.
+	 */
 	public void removeDefaultNamespace() {
 		removeNamespace(null);
 	}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/GapContent.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/GapContent.java
index 21a8ac3..f404974 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/GapContent.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/GapContent.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay and others.
+ * Copyright (c) 2004, 2013 John Krasnay and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
  * Contributors:
  *     John Krasnay - initial API and implementation
  *     Igor Jacy Lino Campista - Java 5 warnings fixed (bug 311325)
+ *     Florian Thienel - refactoring to full fledged DOM
  *******************************************************************************/
 package org.eclipse.vex.core.internal.dom;
 
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/INodeVisitor.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/INodeVisitor.java
index 04c2699..7c73aed 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/INodeVisitor.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/INodeVisitor.java
@@ -15,7 +15,6 @@
  * nodes of the structural part of the DOM.

  * 

  * @author Florian Thienel

- * 

  */

 public interface INodeVisitor {

 

diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/INodeVisitorWithResult.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/INodeVisitorWithResult.java
index d2143a3..d49383a 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/INodeVisitorWithResult.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/INodeVisitorWithResult.java
@@ -15,7 +15,6 @@
  * nodes of the structural part of the DOM and is able to return a value of a certain type.

  * 

  * @author Florian Thienel

- * 

  */

 public interface INodeVisitorWithResult<T> {

 

diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/IWhitespacePolicy.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/IWhitespacePolicy.java
index 0694660..47ae73f 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/IWhitespacePolicy.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/IWhitespacePolicy.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay and others.
+ * Copyright (c) 2004, 2013 John Krasnay and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  * 
  * Contributors:
  *     John Krasnay - initial API and implementation
+ *     Florian Thienel - a NULL object
  *******************************************************************************/
 package org.eclipse.vex.core.internal.dom;
 
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/IWhitespacePolicyFactory.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/IWhitespacePolicyFactory.java
index d20fd18..4a28684 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/IWhitespacePolicyFactory.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/IWhitespacePolicyFactory.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay and others.
+ * Copyright (c) 2004, 2013 John Krasnay and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  * 
  * Contributors:
  *     John Krasnay - initial API and implementation
+ *     Florian Thienel - a NULL object
  *******************************************************************************/
 package org.eclipse.vex.core.internal.dom;
 
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Namespace.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Namespace.java
index 2333a3f..8798d35 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Namespace.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Namespace.java
@@ -1,5 +1,5 @@
 /*******************************************************************************

- * Copyright (c) 2010 Florian Thienel and others.

+ * Copyright (c) 2010, 2013 Florian Thienel and others.

  * All rights reserved. This program and the accompanying materials

  * are made available under the terms of the Eclipse Public License v1.0

  * which accompanies this distribution, and is available at

diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Node.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Node.java
index 3f61d96..324cd76 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Node.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Node.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2012 John Krasnay and others.
+ * Copyright (c) 2004, 2013 John Krasnay and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
  * 
  * Contributors:
  *     John Krasnay - initial API and implementation
+ *     Florian Thienel - refactoring to full fledged DOM
  *******************************************************************************/
 package org.eclipse.vex.core.internal.dom;
 
@@ -18,8 +19,9 @@
 import org.eclipse.core.runtime.QualifiedName;
 
 /**
- * This class represents one node within the XML structure, which is also associated to a region of the textual content.
- * It is the base class for all representatives of the XML structure in the document object model (DOM).
+ * A representation of one node in the XML structure. A node is associated to a range of the textual content.
+ * <p>
+ * This is the base class for all representatives of the XML structure in the document object model (DOM).
  */
 public abstract class Node {
 
@@ -46,14 +48,12 @@
 	}
 
 	/**
-	 * Associates this node to a region within the given content.
+	 * Associate this node to a range within the given content.
 	 * 
 	 * @param content
 	 *            Content object holding the node's content
-	 * @param startOffset
-	 *            offset at which the node's content starts
-	 * @param endOffset
-	 *            offset at which the node's content ends
+	 * @param range
+	 *            the range of this node's content
 	 */
 	public void associate(final Content content, final ContentRange range) {
 		if (isAssociated()) {
@@ -66,10 +66,10 @@
 	}
 
 	/**
-	 * Dissociates this node from its associated content region.
+	 * Dissociates this node from its associated content range.
 	 */
 	public void dissociate() {
-		Assert.isTrue(isAssociated(), "Node must be associated to a Content region before it can be dissociated.");
+		Assert.isTrue(isAssociated(), "This node must be associated to a ContentRange before it can be dissociated.");
 
 		content.removePosition(startPosition);
 		content.removePosition(endPosition);
@@ -93,35 +93,47 @@
 	}
 
 	/**
-	 * The start offset of this node, which eventually also includes the position of an element marker.
+	 * The start offset of this node, which eventually also includes the position of a tag marker.
 	 * 
 	 * @return the start offset of this node within the textual content
 	 */
 	public int getStartOffset() {
-		Assert.isTrue(isAssociated(), "Node must be associated to a Content region to have a start offset.");
+		Assert.isTrue(isAssociated(), "Node must be associated to a ContentRange to have a start offset.");
 		return startPosition.getOffset();
 	}
 
 	/**
-	 * The end offset of this node, which eventually also includes the position of an element marker.
+	 * The end offset of this node, which eventually also includes the position of a tag marker.
 	 * 
 	 * @return the end offset of this node within the textual content
 	 */
 	public int getEndOffset() {
-		Assert.isTrue(isAssociated(), "Node must be associated to a Content region to have an end offset.");
+		Assert.isTrue(isAssociated(), "Node must be associated to a ContentRange to have an end offset.");
 		return endPosition.getOffset();
 	}
 
+	/**
+	 * @return the range in the content to which this node is associated, eventually including tag markers
+	 */
 	public ContentRange getRange() {
 		return new ContentRange(getStartOffset(), getEndOffset());
 	}
 
+	/**
+	 * Indicate whether this node has no content beside its tag markers. If this node is not associated with textual
+	 * content, this method returns false.
+	 * 
+	 * @return true if this node has no content beside its tag markers
+	 */
 	public boolean isEmpty() {
+		if (!isAssociated()) {
+			return false;
+		}
 		return getEndOffset() - getStartOffset() == 1;
 	}
 
 	/**
-	 * Indicates whether the given offset is within the boundaries of this node. If this node is not associated with
+	 * Indicate whether the given offset is within the boundaries of this node. If this node is not associated with
 	 * textual content, this method returns false.
 	 * 
 	 * @param offset
@@ -136,13 +148,11 @@
 	}
 
 	/**
-	 * Indicates whether this node is fully within the given range. If this node is not associated with textual content,
+	 * Indicate whether this node is fully within the given range. If this node is not associated with textual content,
 	 * this method returns false.
 	 * 
-	 * @param startOffset
-	 *            the range's start offset
-	 * @param endOffset
-	 *            the range's end offst
+	 * @param range
+	 *            the range
 	 * @return true if this node is fully within the given range
 	 */
 	public boolean isInRange(final ContentRange range) {
@@ -153,9 +163,7 @@
 	}
 
 	/**
-	 * The textual content, not inluding any element markers.
-	 * 
-	 * @return the textual content of this node
+	 * @return the textual content of this node, not including any tag markers
 	 */
 	public String getText() {
 		return getText(getRange());
@@ -164,10 +172,8 @@
 	/**
 	 * The textual content in the given range, not including any element markers.
 	 * 
-	 * @param startOffset
-	 *            the start offset
-	 * @param endOffset
-	 *            the end offset
+	 * @param range
+	 *            the range of the textual content
 	 * @return the textual content in the given range
 	 */
 	public String getText(final ContentRange range) {
@@ -175,6 +181,9 @@
 		return content.getText(range.intersection(getRange()));
 	}
 
+	/**
+	 * @return the document to which this node belongs, or null if this node does not belong to any document
+	 */
 	public Document getDocument() {
 		return getDocument(this);
 	}
@@ -193,10 +202,19 @@
 		return getDocument(parent);
 	}
 
+	/**
+	 * Indicate whether this and the given node are of the same kind (e.g. elements with the same qualified name).
+	 * 
+	 * @return true if this and the given node are of the same kind
+	 */
 	public boolean isKindOf(final Node node) {
 		return false;
 	}
 
+	/**
+	 * @see Element#setBaseURI(String)
+	 * @return the base URI of this node
+	 */
 	public String getBaseURI() {
 		if (getParent() != null) {
 			return getParent().getBaseURI();
@@ -225,6 +243,9 @@
 	 */
 	public abstract <T> T accept(final INodeVisitorWithResult<T> visitor);
 
+	/**
+	 * @return the qualified names of the given nodes
+	 */
 	public static List<QualifiedName> getNodeNames(final Collection<Node> nodes) {
 		final List<QualifiedName> names = new ArrayList<QualifiedName>(nodes.size());
 
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Parent.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Parent.java
index ecc0899..43d9027 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Parent.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Parent.java
@@ -20,7 +20,7 @@
 

 /**

  * A Parent node is a Node which can contain other nodes as children. This class defines the tree-like structure of the

- * DOM. It handles the mergin of the child nodes and the textual content of one node within the structure of the

+ * DOM. It handles the merging of the child nodes and the textual content of one node within the structure of the

  * document.

  * 

  * @author Florian Thienel

@@ -56,6 +56,9 @@
 		child.setParent(this);

 	}

 

+	/**

+	 * @return the child node of this parent following the given offset

+	 */

 	public int getIndexOfChildNextTo(final int offset) {

 		final ContentRange insertionRange = getRange().resizeBy(1, 0);

 		Assert.isTrue(insertionRange.contains(offset), MessageFormat.format("The offset must be within {0}.", insertionRange));

@@ -153,6 +156,9 @@
 		return currentOffset;

 	}

 

+	/**

+	 * @return all child nodes before the given offset, including Text nodes

+	 */

 	public List<Node> getChildNodesBefore(final int offset) {

 		if (offset <= getStartOffset()) {

 			return Collections.emptyList();

@@ -160,6 +166,9 @@
 		return getChildNodes(new ContentRange(getStartOffset() + 1, offset));

 	}

 

+	/**

+	 * @return all child nodes after the given offset, including Text nodes

+	 */

 	public List<Node> getChildNodesAfter(final int offset) {

 		if (offset >= getEndOffset()) {

 			return Collections.emptyList();

@@ -168,7 +177,7 @@
 	}

 

 	/**

-	 * An Iterator of all child nodes. The underlying collection is not modifyable.

+	 * An Iterator of all child nodes including Text nodes. The underlying collection is not modifyable.

 	 * 

 	 * @see Parent#getChildNodes()

 	 * @see Iterator

@@ -199,7 +208,7 @@
 	}

 

 	/**

-	 * Returns the node at the given offset.

+	 * Returns the child node which contains the given offset, or this node, if no child contains the offset.

 	 * 

 	 * @param offset

 	 *            the offset

@@ -221,10 +230,10 @@
 	}

 

 	/**

-	 * Indicates if this parent node has child nodes. Text nodes are ignored, i.e. this method will return false if this

-	 * parent node contains only text.

+	 * Indicates whether this parent node has child nodes. Text nodes are ignored, i.e. this method will return false if

+	 * this parent node contains only text.

 	 * 

-	 * @return true if this parent node has child nodes

+	 * @return true if this parent node has any child nodes besides text

 	 */

 	public boolean hasChildren() {

 		return !children.isEmpty();

diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Position.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Position.java
index c56b904..4eb5ca6 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Position.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Position.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay and others.
+ * Copyright (c) 2004, 2013 John Krasnay and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,13 +7,14 @@
  * 
  * Contributors:
  *     John Krasnay - initial API and implementation
+ *     Florian Thienel - NULL object
  *******************************************************************************/
 package org.eclipse.vex.core.internal.dom;
 
 /**
  * Represents a logical location in a document. As the document is modified, existing <code>Position</code> objects are
  * updated to reflect the appropriate character offset in the document.
- * 
+ * <p>
  * Positions can be invalid if they were removed from their associated Content instance. Invalid positions do not get
  * updated on content modifications. They must not be used for anything anymore.
  */
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Text.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Text.java
index 131a7e8..9233397 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Text.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Text.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay and others.
+ * Copyright (c) 2004, 2013 John Krasnay and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -7,17 +7,21 @@
  * 
  * Contributors:
  *     John Krasnay - initial API and implementation
+ *     Florian Thienel - refactoring to full fledged DOM
  *******************************************************************************/
 package org.eclipse.vex.core.internal.dom;
 
 /**
- * <code>Text</code> represents a run of text in a document. Text objects are not used in the internal document
- * structure; they are only returned as needed by the <code>Element.getContent</code> method.
+ * A representation of textual content of an XML document within the DOM. Text objects are not used in the internal
+ * document structure; they are dynamically created as needed by the <code>Element.getChildNodes()</code> method.
+ * 
+ * @see Element#getChildNodes()
  */
 public class Text extends Node {
 
 	/**
-	 * Class constructor.
+	 * Create a new Text node for the given range in the given content. This constructor automatically associates the
+	 * Text node with the given content and sets its parent.
 	 * 
 	 * @param parent
 	 *            The parent node containing the text
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Validator.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Validator.java
index 2054ba7..6e4842f 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Validator.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Validator.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2004, 2008 John Krasnay and others.
+ * Copyright (c) 2004, 2013 John Krasnay and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
  * Contributors:
  *     John Krasnay - initial API and implementation
  *     Igor Jacy Lino Campista - Java 5 warnings fixed (bug 311325)
+ *     Florian Thienel - support for XML namespaces (bug 253753)
  *******************************************************************************/
 package org.eclipse.vex.core.internal.dom;