	public IRegion getDamageRegion(ITypedRegion partition, final DocumentEvent e, boolean documentPartitioningChanged) {
		if (documentPartitioningChanged)
			return partition;
		IRegion result = getDocument().readOnly(new UnitOfWork<IRegion>(){
			private final int offset = e.getOffset();
			private final int endOffset = offset + e.getLength();
			public IRegion exec(XtextResource resource) throws Exception {
				AbstractNode node = resource.getParseResult().getRootNode();
				AbstractNode start = null;
				AbstractNode end = null;
				while(node != null && start == null) {
					if (node instanceof CompositeNode) {
						for(AbstractNode child: ((CompositeNode) node).getChildren()) {
							if (child.getTotalOffset() <= offset && child.getTotalOffset() + child.getTotalLength() >= offset) {
								node = child;
								if (node instanceof LeafNode || node.getTotalOffset() == offset)
									start = node;
								break;
							}
						}
					} else {
						throw new IllegalStateException("node is not in expected range but is not a composite.");
					}
				}
				node = start;
				while(node != null && end == null) {
					if (node.getTotalLength() + node.getTotalOffset() >= endOffset) {
						while(end == null) {
							if (node instanceof CompositeNode) {
								for(int i = ((CompositeNode) node).getChildren().size() - 1; i >= 0; i--) {
									AbstractNode child = ((CompositeNode) node).getChildren().get(i);
									if (child.getTotalOffset() + child.getTotalLength() >= endOffset && child.getTotalOffset() <= endOffset) {
										node = child;
										if (node instanceof LeafNode || node.getTotalOffset() + node.getTotalLength() == endOffset)
											end = node;
										break;
									}
								}
							} else {
								end = node;
							}
						}
					} else {
						node = node.getParent();
					}
				}
				int startOffset = start != null ? start.getTotalOffset() : offset;
				int endOffset = end != null ? end.getTotalOffset() + end.getTotalLength() : this.endOffset;
				Range range = new Range(startOffset, endOffset);
				range.mergeAllErrors(resource.getParseResult().getRootNode());
				return new Region(range.getFromOffset(), range.getToOffset() - range.getFromOffset() + e.getText().length() - e.getLength());
			}
		});
		return result;
	}

	public IRegion getDamageRegion(ITypedRegion partition, final DocumentEvent e, boolean documentPartitioningChanged) {
		if (documentPartitioningChanged)
			return partition;
		IRegion result = getDocument().readOnly(new UnitOfWork<IRegion>(){
			private final int offset = e.getOffset();
			private final int endOffset = offset + e.getLength();
			public IRegion exec(XtextResource resource) throws Exception {
				AbstractNode node = resource.getParseResult().getRootNode();
				AbstractNode start = null;
				AbstractNode end = null;
				while(node != null && start == null) {
					if (node instanceof CompositeNode) {
						if (((CompositeNode) node).getChildren().isEmpty())
							break;
						for(AbstractNode child: ((CompositeNode) node).getChildren()) {
							if (child.getTotalOffset() <= offset && child.getTotalOffset() + child.getTotalLength() >= offset) {
								node = child;
								if (node instanceof LeafNode || node.getTotalOffset() == offset)
									start = node;
								break;
							}
						}
					} else {
						throw new IllegalStateException("node is not in expected range but is not a composite.");
					}
				}
				node = start;
				while(node != null && end == null) {
					if (node.getTotalLength() + node.getTotalOffset() >= endOffset) {
						while(end == null) {
							if (node instanceof CompositeNode) {
								for(int i = ((CompositeNode) node).getChildren().size() - 1; i >= 0; i--) {
									AbstractNode child = ((CompositeNode) node).getChildren().get(i);
									if (child.getTotalOffset() + child.getTotalLength() >= endOffset && child.getTotalOffset() <= endOffset) {
										node = child;
										if (node instanceof LeafNode || node.getTotalOffset() + node.getTotalLength() == endOffset)
											end = node;
										break;
									}
								}
							} else {
								end = node;
							}
						}
					} else {
						node = node.getParent();
					}
				}
				int startOffset = start != null ? start.getTotalOffset() : offset;
				int endOffset = end != null ? end.getTotalOffset() + end.getTotalLength() : this.endOffset;
				Range range = new Range(startOffset, endOffset);
				range.mergeAllErrors(resource.getParseResult().getRootNode());
				return new Region(range.getFromOffset(), range.getToOffset() - range.getFromOffset() + e.getText().length() - e.getLength());
			}
		});
		return result;
	}
