Removed Positions get flagged "invalid" for a better ease of use.

Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ContentTest.java b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ContentTest.java
index 6342130..34fa2ff 100644
--- a/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ContentTest.java
+++ b/org.eclipse.vex.core.tests/src/org/eclipse/vex/core/internal/dom/ContentTest.java
@@ -11,6 +11,7 @@
 package org.eclipse.vex.core.internal.dom;

 

 import static org.junit.Assert.assertEquals;

+import static org.junit.Assert.assertFalse;

 import static org.junit.Assert.assertTrue;

 

 import org.junit.Before;

@@ -178,4 +179,14 @@
 		content.insertText(1, "Hello");

 		assertEquals(1, position.getOffset());

 	}

+

+	@Test

+	public void invalidatesPositionsOnRemoval() throws Exception {

+		content.insertElementMarker(0);

+		content.insertElementMarker(0);

+		final Position position = content.createPosition(1);

+		assertTrue(position.isValid());

+		content.removePosition(position);

+		assertFalse(position.isValid());

+	}

 }

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 5dedfa6..b2da67a 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
@@ -60,7 +60,13 @@
 	}
 
 	public void removePosition(final Position position) {
-		positions.remove(position);
+		if (positions.remove(position)) {
+			/*
+			 * This cast is save: if the position can be removed, this instance must have created it, hence it is a
+			 * GapContentPosition.
+			 */
+			((GapContentPosition) position).invalidate();
+		}
 	}
 
 	/**
@@ -248,6 +254,8 @@
 
 		private int offset;
 
+		private boolean valid = true;
+
 		public GapContentPosition(final int offset) {
 			this.offset = offset;
 		}
@@ -260,6 +268,14 @@
 			this.offset = offset;
 		}
 
+		public boolean isValid() {
+			return valid;
+		};
+
+		public void invalidate() {
+			valid = false;
+		}
+
 		@Override
 		public String toString() {
 			return Integer.toString(offset);
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 69f6243..c56b904 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
@@ -13,6 +13,9 @@
 /**
  * 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.
+ * 
+ * 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.
  */
 public interface Position {
 
@@ -20,6 +23,10 @@
 		public int getOffset() {
 			return -1;
 		}
+
+		public boolean isValid() {
+			return false;
+		};
 	};
 
 	/**
@@ -27,4 +34,9 @@
 	 */
 	int getOffset();
 
+	/**
+	 * @return true if this position is still valid and actively maintained by its creator
+	 */
+	boolean isValid();
+
 }