/*******************************************************************************
 * Copyright (c) 2000, 2008 IBM Corporation 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
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jface.text.projection;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.text.AbstractDocument;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.BadPositionCategoryException;
import org.eclipse.jface.text.DefaultLineTracker;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentExtension;
import org.eclipse.jface.text.IDocumentExtension2;
import org.eclipse.jface.text.IDocumentInformationMapping;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.ILineTracker;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextStore;
import org.eclipse.jface.text.Position;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextUtilities;


/**
 * A <code>ProjectionDocument</code> represents a projection of its master
 * document. The contents of a projection document is a sequence of fragments of
 * the master document, i.e. the projection document can be thought as being
 * constructed from the master document by not copying the whole master document
 * but omitting several ranges of the master document.
 * <p>
 * The projection document indirectly utilizes its master document as
 * <code>ITextStore</code> by means of a <code>ProjectionTextStore</code>.
 * <p>
 * The content of a projection document can be changed in two ways. Either by a
 * text replace applied to the master document or the projection document. Or by
 * changing the projection between the master document and the projection
 * document. For the latter the two methods <code>addMasterDocumentRange</code>
 * and <code>removeMasterDocumentRange</code> are provided. For any
 * manipulation, the projection document sends out a
 * {@link org.eclipse.jface.text.projection.ProjectionDocumentEvent} describing
 * the change.
 * <p>
 * Clients are not supposed to directly instantiate this class. In order to
 * obtain a projection document, a
 * {@link org.eclipse.jface.text.projection.ProjectionDocumentManager}should be
 * used. This class is not intended to be subclassed outside of its origin
 * package.</p>
 *
 * @since 3.0
 * @noinstantiate This class is not intended to be instantiated by clients.
 * @noextend This class is not intended to be subclassed by clients.
 */
public class ProjectionDocument extends AbstractDocument {


	/**
	 * Prefix of the name of the position category used to keep track of the master
	 * document's fragments that correspond to the segments of the projection
	 * document.
	 */
	private final static String FRAGMENTS_CATEGORY_PREFIX= "__fragmentsCategory"; //$NON-NLS-1$

	/**
	 * Name of the position category used to keep track of the project
	 * document's segments that correspond to the fragments of the master
	 * document.
	 */
	private final static String SEGMENTS_CATEGORY= "__segmentsCategory"; //$NON-NLS-1$


	/** The master document */
	private IDocument fMasterDocument;
	/** The master document as document extension */
	private IDocumentExtension fMasterDocumentExtension;
	/** The fragments' position category */
	private String fFragmentsCategory;
	/** The segment's position category */
	private String fSegmentsCategory;
	/** The document event issued by the master document */
	private DocumentEvent fMasterEvent;
	/** The document event to be issued by the projection document */
	private ProjectionDocumentEvent fSlaveEvent;
	/** The original document event generated by a direct manipulation of this projection document */
	private DocumentEvent fOriginalEvent;
	/** Indicates whether the projection document initiated a master document update or not */
	private boolean fIsUpdating= false;
	/** Indicated whether the projection document is in auto expand mode nor not */
	private boolean fIsAutoExpanding= false;
	/** The position updater for the segments */
	private SegmentUpdater fSegmentUpdater;
	/** The position updater for the fragments */
	private FragmentUpdater fFragmentsUpdater;
	/** The projection mapping */
	private ProjectionMapping fMapping;

	/**
	 * Creates a projection document for the given master document.
	 *
	 * @param masterDocument the master document
	 */
	public ProjectionDocument(IDocument masterDocument) {
		super();

		fMasterDocument= masterDocument;
		if (fMasterDocument instanceof IDocumentExtension)
			fMasterDocumentExtension= (IDocumentExtension) fMasterDocument;

		fSegmentsCategory= SEGMENTS_CATEGORY;
		fFragmentsCategory= FRAGMENTS_CATEGORY_PREFIX + hashCode();
		fMasterDocument.addPositionCategory(fFragmentsCategory);
		fFragmentsUpdater= new FragmentUpdater(fFragmentsCategory);
		fMasterDocument.addPositionUpdater(fFragmentsUpdater);

		fMapping= new ProjectionMapping(masterDocument, fFragmentsCategory, this, fSegmentsCategory);

		ITextStore s= new ProjectionTextStore(masterDocument, fMapping);
		ILineTracker tracker= new DefaultLineTracker();

		setTextStore(s);
		setLineTracker(tracker);

		completeInitialization();

		initializeProjection();
		tracker.set(s.get(0, s.getLength()));
	}

	/**
	 * Disposes this projection document.
	 */
	public void dispose() {
		fMasterDocument.removePositionUpdater(fFragmentsUpdater);
		try {
			fMasterDocument.removePositionCategory(fFragmentsCategory);
		} catch (BadPositionCategoryException x) {
			// allow multiple dispose calls
		}
	}

	private void internalError() {
		throw new IllegalStateException();
	}

	/**
	 * Returns the fragments of the master documents.
	 *
	 * @return the fragment of the master document
	 */
	protected final Position[] getFragments() {
		try {
			return fMasterDocument.getPositions(fFragmentsCategory);
		} catch (BadPositionCategoryException e) {
			internalError();
		}
		// unreachable
		return null;
	}

	/**
	 * Returns the segments of this projection document.
	 *
	 * @return the segments of this projection document
	 */
	protected final Position[] getSegments() {
		try {
			return getPositions(fSegmentsCategory);
		} catch (BadPositionCategoryException e) {
			internalError();
		}
		// unreachable
		return null;
	}

	/**
	 * Returns the projection mapping used by this document.
	 * 
	 * @return the projection mapping used by this document
	 * @deprecated As of 3.4, replaced by {@link #getDocumentInformationMapping()}
	 */
	public ProjectionMapping getProjectionMapping(){
		return fMapping;
	}
	
	/**
	 * Returns the projection mapping used by this document.
	 * 
	 * @return the projection mapping used by this document
	 * @since 3.4
	 */
	public IDocumentInformationMapping getDocumentInformationMapping() {
		return fMapping;
	}

	/**
	 * Returns the master document of this projection document.
	 *
	 * @return the master document of this projection document
	 */
	public IDocument getMasterDocument() {
		return fMasterDocument;
	}
	
	/*
	 * @see org.eclipse.jface.text.IDocumentExtension4#getDefaultLineDelimiter()
	 * @since 3.1
	 */
	public String getDefaultLineDelimiter() {
		return TextUtilities.getDefaultLineDelimiter(fMasterDocument);
	}
	
	/**
	 * Initializes the projection document from the master document based on
	 * the master's fragments.
	 */
	private void initializeProjection() {

		try {

			addPositionCategory(fSegmentsCategory);
			fSegmentUpdater= new SegmentUpdater(fSegmentsCategory);
			addPositionUpdater(fSegmentUpdater);

			int offset= 0;
			Position[] fragments= getFragments();
			for (int i= 0; i < fragments.length; i++) {
				Fragment fragment= (Fragment) fragments[i];
				Segment segment= new Segment(offset, fragment.getLength());
				segment.fragment= fragment;
				addPosition(fSegmentsCategory, segment);
				offset += fragment.length;
			}

		} catch (BadPositionCategoryException x) {
			internalError();
		} catch (BadLocationException x) {
			internalError();
		}
	}

	/**
	 * Creates a segment for the given fragment at the given position inside the list of segments.
	 *
	 * @param fragment the corresponding fragment
	 * @param index the index in the list of segments
	 * @return the created segment
	 * @throws BadLocationException in case the fragment is invalid
	 * @throws BadPositionCategoryException in case the segment category is invalid
	 */
	private Segment createSegmentFor(Fragment fragment, int index) throws BadLocationException, BadPositionCategoryException {

		int offset= 0;
		if (index > 0) {
			Position[] segments= getSegments();
			Segment segment= (Segment) segments[index - 1];
			offset= segment.getOffset() + segment.getLength();
		}

		Segment segment= new Segment(offset, 0);
		segment.fragment= fragment;
		fragment.segment= segment;
		addPosition(fSegmentsCategory, segment);
		return segment;
	}

	/**
	 * Adds the given range of the master document to this projection document.
	 *
	 * @param offsetInMaster offset of the master document range
	 * @param lengthInMaster length of the master document range
	 * @param masterDocumentEvent the master document event that causes this
	 *            projection change or <code>null</code> if none
	 * @throws BadLocationException if the given range is invalid in the master
	 *             document
	 */
	private void internalAddMasterDocumentRange(int offsetInMaster, int lengthInMaster, DocumentEvent masterDocumentEvent) throws BadLocationException {
		if (lengthInMaster == 0)
			return;

		try {

			Position[] fragments= getFragments();
			int index= fMasterDocument.computeIndexInCategory(fFragmentsCategory, offsetInMaster);

			Fragment left= null;
			Fragment right= null;

			if (index < fragments.length) {
				Fragment fragment= (Fragment) fragments[index];
				if (offsetInMaster == fragment.offset)
					if (fragment.length == 0) // the fragment does not overlap - it is a zero-length fragment at the same offset
						left= fragment;
					else
						throw new IllegalArgumentException("overlaps with existing fragment"); //$NON-NLS-1$
				if (offsetInMaster + lengthInMaster == fragment.offset)
					right= fragment;
			}

			if (0 < index && index <= fragments.length) {
				Fragment fragment= (Fragment) fragments[index - 1];
				if (fragment.includes(offsetInMaster))
					throw new IllegalArgumentException("overlaps with existing fragment"); //$NON-NLS-1$
				if (fragment.getOffset() + fragment.getLength() == offsetInMaster)
					left= fragment;
			}

			int offsetInSlave= 0;
			if (index > 0) {
				Fragment fragment= (Fragment) fragments[index - 1];
				Segment segment= fragment.segment;
				offsetInSlave= segment.getOffset() + segment.getLength();
			}

			ProjectionDocumentEvent event= new ProjectionDocumentEvent(this, offsetInSlave, 0, fMasterDocument.get(offsetInMaster, lengthInMaster), offsetInMaster, lengthInMaster, masterDocumentEvent);
			super.fireDocumentAboutToBeChanged(event);

			// check for neighboring fragment
			if (left != null && right != null) {

				int endOffset= right.getOffset() + right.getLength();
				left.setLength(endOffset - left.getOffset());
				left.segment.setLength(left.segment.getLength() + right.segment.getLength());

				removePosition(fSegmentsCategory, right.segment);
				fMasterDocument.removePosition(fFragmentsCategory, right);

			} else if (left != null) {
				int endOffset= offsetInMaster +lengthInMaster;
				left.setLength(endOffset - left.getOffset());
				left.segment.markForStretch();

			} else if (right != null) {
				right.setOffset(right.getOffset() - lengthInMaster);
				right.setLength(right.getLength() + lengthInMaster);
				right.segment.markForStretch();

			} else {
				// create a new segment
				Fragment fragment= new Fragment(offsetInMaster, lengthInMaster);
				fMasterDocument.addPosition(fFragmentsCategory, fragment);
				Segment segment= createSegmentFor(fragment, index);
				segment.markForStretch();
			}

			getTracker().replace(event.getOffset(), event.getLength(), event.getText());
			super.fireDocumentChanged(event);

		} catch (BadPositionCategoryException x) {
			internalError();
		}
	}

	/**
	 * Finds the fragment of the master document that represents the given range.
	 *
	 * @param offsetInMaster the offset of the range in the master document
	 * @param lengthInMaster the length of the range in the master document
	 * @return the fragment representing the given master document range
	 */
	private Fragment findFragment(int offsetInMaster, int lengthInMaster) {
		Position[] fragments= getFragments();
		for (int i= 0; i < fragments.length; i++) {
			Fragment f= (Fragment) fragments[i];
			if (f.getOffset() <= offsetInMaster && offsetInMaster + lengthInMaster <= f.getOffset() + f.getLength())
				return f;
		}
		return null;
	}

	/**
	 * Removes the given range of the master document from this projection
	 * document.
	 *
	 * @param offsetInMaster the offset of the range in the master document
	 * @param lengthInMaster the length of the range in the master document
	 *
	 * @throws BadLocationException if the given range is not valid in the
	 *             master document
	 * @throws IllegalArgumentException if the given range is not projected in
	 *             this projection document or is not completely comprised by
	 *             an existing fragment
	 */
	private void internalRemoveMasterDocumentRange(int offsetInMaster, int lengthInMaster) throws BadLocationException {
		try {

			IRegion imageRegion= fMapping.toExactImageRegion(new Region(offsetInMaster, lengthInMaster));
			if (imageRegion == null)
				throw new IllegalArgumentException();

			Fragment fragment= findFragment(offsetInMaster, lengthInMaster);
			if (fragment == null)
				throw new IllegalArgumentException();

			ProjectionDocumentEvent event= new ProjectionDocumentEvent(this, imageRegion.getOffset(), imageRegion.getLength(), "", offsetInMaster, lengthInMaster); //$NON-NLS-1$
			super.fireDocumentAboutToBeChanged(event);

			if (fragment.getOffset() == offsetInMaster) {
				fragment.setOffset(offsetInMaster + lengthInMaster);
				fragment.setLength(fragment.getLength() - lengthInMaster);
			} else if (fragment.getOffset() + fragment.getLength() == offsetInMaster + lengthInMaster) {
				fragment.setLength(fragment.getLength() - lengthInMaster);
			} else {
				// split fragment into three fragments, let position updater remove it

				// add fragment for the region to be removed
				Fragment newFragment= new Fragment(offsetInMaster, lengthInMaster);
				Segment segment= new Segment(imageRegion.getOffset(), imageRegion.getLength());
				newFragment.segment= segment;
				segment.fragment= newFragment;
				fMasterDocument.addPosition(fFragmentsCategory, newFragment);
				addPosition(fSegmentsCategory, segment);

				// add fragment for the remainder right of the deleted range in the original fragment
				int offset= offsetInMaster + lengthInMaster;
				newFragment= new Fragment(offset, fragment.getOffset() + fragment.getLength() - offset);
				offset= imageRegion.getOffset() + imageRegion.getLength();
				segment= new Segment(offset, fragment.segment.getOffset() + fragment.segment.getLength() - offset);
				newFragment.segment= segment;
				segment.fragment= newFragment;
				fMasterDocument.addPosition(fFragmentsCategory, newFragment);
				addPosition(fSegmentsCategory, segment);

				// adjust length of initial fragment (the left one)
				fragment.setLength(offsetInMaster - fragment.getOffset());
				fragment.segment.setLength(imageRegion.getOffset() - fragment.segment.getOffset());
			}

			getTracker().replace(event.getOffset(), event.getLength(), event.getText());
			super.fireDocumentChanged(event);

		} catch (BadPositionCategoryException x) {
			internalError();
		}
	}

	/**
	 * Returns the sequence of all master document regions which are contained
	 * in the given master document range and which are not yet part of this
	 * projection document.
	 *
	 * @param offsetInMaster the range offset in the master document
	 * @param lengthInMaster the range length in the master document
	 * @return the sequence of regions which are not yet part of the projection
	 *         document
	 * @throws BadLocationException in case the given range is invalid in the
	 *         master document
	 */
	public final IRegion[] computeUnprojectedMasterRegions(int offsetInMaster, int lengthInMaster) throws BadLocationException {

		IRegion[] fragments= null;
		IRegion imageRegion= fMapping.toImageRegion(new Region(offsetInMaster, lengthInMaster));
		if (imageRegion != null)
			fragments= fMapping.toExactOriginRegions(imageRegion);

		if (fragments == null || fragments.length == 0)
			return new IRegion[] { new Region(offsetInMaster, lengthInMaster) };

		List gaps= new ArrayList();

		IRegion region= fragments[0];
		if (offsetInMaster < region.getOffset())
			gaps.add(new Region(offsetInMaster, region.getOffset() - offsetInMaster));

		for (int i= 0; i < fragments.length - 1; i++) {
			IRegion left= fragments[i];
			IRegion right= fragments[i + 1];
			int leftEnd= left.getOffset() + left.getLength();
			if (leftEnd < right.getOffset())
				gaps.add(new Region(leftEnd, right.getOffset() - leftEnd));
		}

		region= fragments[fragments.length - 1];
		int leftEnd= region.getOffset() + region.getLength();
		int rightEnd= offsetInMaster + lengthInMaster;
		if (leftEnd < rightEnd)
			gaps.add(new Region(leftEnd, rightEnd - leftEnd));

		IRegion[] result= new IRegion[gaps.size()];
		gaps.toArray(result);
		return result;
	}

	/**
	 * Returns the first master document region which is contained in the given
	 * master document range and which is not yet part of this projection
	 * document.
	 *
	 * @param offsetInMaster the range offset in the master document
	 * @param lengthInMaster the range length in the master document
	 * @return the first region that is not yet part of the projection document
	 * @throws BadLocationException in case the given range is invalid in the
	 *         master document
	 * @since 3.1
	 */
	private IRegion computeFirstUnprojectedMasterRegion(int offsetInMaster, int lengthInMaster) throws BadLocationException {

		IRegion[] fragments= null;
		IRegion imageRegion= fMapping.toImageRegion(new Region(offsetInMaster, lengthInMaster));
		if (imageRegion != null)
			fragments= fMapping.toExactOriginRegions(imageRegion);

		if (fragments == null || fragments.length == 0)
			return new Region(offsetInMaster, lengthInMaster);

		IRegion region= fragments[0];
		if (offsetInMaster < region.getOffset())
			return new Region(offsetInMaster, region.getOffset() - offsetInMaster);

		for (int i= 0; i < fragments.length - 1; i++) {
			IRegion left= fragments[i];
			IRegion right= fragments[i + 1];
			int leftEnd= left.getOffset() + left.getLength();
			if (leftEnd < right.getOffset())
				return new Region(leftEnd, right.getOffset() - leftEnd);
		}

		region= fragments[fragments.length - 1];
		int leftEnd= region.getOffset() + region.getLength();
		int rightEnd= offsetInMaster + lengthInMaster;
		if (leftEnd < rightEnd)
			return new Region(leftEnd, rightEnd - leftEnd);

		return null;
	}

	/**
	 * Ensures that the given range of the master document is part of this
	 * projection document.
	 *
	 * @param offsetInMaster the offset of the master document range
	 * @param lengthInMaster the length of the master document range
	 * @throws BadLocationException in case the master event is not valid
	 */
	public void addMasterDocumentRange(int offsetInMaster, int lengthInMaster) throws BadLocationException {
		addMasterDocumentRange(offsetInMaster, lengthInMaster, null);
	}

	/**
	 * Ensures that the given range of the master document is part of this
	 * projection document.
	 *
	 * @param offsetInMaster the offset of the master document range
	 * @param lengthInMaster the length of the master document range
	 * @param masterDocumentEvent the master document event which causes this
	 *            projection change, or <code>null</code> if none
	 * @throws BadLocationException in case the master event is not valid
	 */
	private void addMasterDocumentRange(int offsetInMaster, int lengthInMaster, DocumentEvent masterDocumentEvent) throws BadLocationException {
		/*
		 * Calling internalAddMasterDocumentRange may cause other master ranges
		 * to become unfolded, resulting in re-entrant calls to this method. In
		 * order to not add a region twice, we have to compute the next region
		 * to add in every iteration.
		 *
		 * To place an upper bound on the number of iterations, we use the number
		 * of fragments * 2 as the limit.
		 */
		int limit= Math.max(getFragments().length * 2, 20);
		while (true) {
			if (limit-- < 0)
				throw new IllegalArgumentException("safety loop termination"); //$NON-NLS-1$

			IRegion gap= computeFirstUnprojectedMasterRegion(offsetInMaster, lengthInMaster);
			if (gap == null)
				return;

			internalAddMasterDocumentRange(gap.getOffset(), gap.getLength(), masterDocumentEvent);
		}
	}

	/**
	 * Ensures that the given range of the master document is not part of this
	 * projection document.
	 *
	 * @param offsetInMaster the offset of the master document range
	 * @param lengthInMaster the length of the master document range
	 * @throws BadLocationException in case the master event is not valid
	 */
	public void removeMasterDocumentRange(int offsetInMaster, int lengthInMaster) throws BadLocationException {
		IRegion[] fragments= computeProjectedMasterRegions(offsetInMaster, lengthInMaster);
		if (fragments == null || fragments.length == 0)
			return;

		for (int i= 0; i < fragments.length; i++) {
			IRegion fragment= fragments[i];
			internalRemoveMasterDocumentRange(fragment.getOffset(), fragment.getLength());
		}
	}

	/**
	 * Returns the sequence of all master document regions with are contained in the given master document
	 * range and which are part of this projection document. May return <code>null</code> if no such
	 * regions exist.
	 *
	 * @param offsetInMaster the range offset in the master document
	 * @param lengthInMaster the range length in the master document
	 * @return the sequence of regions which are part of the projection document or <code>null</code>
	 * @throws BadLocationException in case the given range is invalid in the master document
	 */
	public final IRegion[] computeProjectedMasterRegions(int offsetInMaster, int lengthInMaster) throws BadLocationException {
		IRegion imageRegion= fMapping.toImageRegion(new Region(offsetInMaster, lengthInMaster));
		return imageRegion != null ? fMapping.toExactOriginRegions(imageRegion) : null;
	}

	/**
	 * Returns whether this projection is being updated.
	 *
	 * @return <code>true</code> if the document is updating
	 */
	protected boolean isUpdating() {
		return fIsUpdating;
	}

	/*
	 * @see org.eclipse.jface.text.IDocument#replace(int, int, java.lang.String)
	 */
	public void replace(int offset, int length, String text) throws BadLocationException {
		try {
			fIsUpdating= true;
			if (fMasterDocumentExtension != null)
				fMasterDocumentExtension.stopPostNotificationProcessing();
			if (fMasterDocument instanceof IDocumentExtension2)
				((IDocumentExtension2)fMasterDocument).stopListenerNotification();
			super.replace(offset, length, text);

		} finally {
			if (fMasterDocument instanceof IDocumentExtension2)
				((IDocumentExtension2)fMasterDocument).resumeListenerNotification();
			fIsUpdating= false;
			if (fMasterDocumentExtension != null)
				fMasterDocumentExtension.resumePostNotificationProcessing();
		}
	}

	/*
	 * @see org.eclipse.jface.text.IDocument#set(java.lang.String)
	 */
	public void set(String text) {
		try {
			fIsUpdating= true;
			if (fMasterDocumentExtension != null)
				fMasterDocumentExtension.stopPostNotificationProcessing();

			super.set(text);

		} finally {
			fIsUpdating= false;
			if (fMasterDocumentExtension != null)
				fMasterDocumentExtension.resumePostNotificationProcessing();
		}
	}

	/**
	 * Transforms a document event of the master document into a projection
	 * document based document event.
	 *
	 * @param masterEvent the master document event
	 * @return the slave document event
	 * @throws BadLocationException in case the master event is not valid
	 */
	private ProjectionDocumentEvent normalize(DocumentEvent masterEvent) throws BadLocationException {
		if (!isUpdating()) {
			IRegion imageRegion= fMapping.toExactImageRegion(new Region(masterEvent.getOffset(), masterEvent.getLength()));
			if (imageRegion != null)
				return new ProjectionDocumentEvent(this, imageRegion.getOffset(), imageRegion.getLength(), masterEvent.getText(), masterEvent);
			return null;
		}

		ProjectionDocumentEvent event= new ProjectionDocumentEvent(this, fOriginalEvent.getOffset(), fOriginalEvent.getLength(), fOriginalEvent.getText(), masterEvent);
		fOriginalEvent= null;
		return event;
	}

	/**
	 * Ensures that when the master event affects this projection document, that the whole region described by the
	 * event is part of this projection document.
	 *
	 * @param masterEvent the master document event
	 * @return <code>true</code> if masterEvent affects this projection document
	 * @throws BadLocationException in case the master event is not valid
	 */
	protected final boolean adaptProjectionToMasterChange(DocumentEvent masterEvent) throws BadLocationException {
		if (!isUpdating() && fFragmentsUpdater.affectsPositions(masterEvent) || fIsAutoExpanding && masterEvent.getLength() > 0) {

			addMasterDocumentRange(masterEvent.getOffset(), masterEvent.getLength(), masterEvent);
			return true;

		} else if (fMapping.getImageLength() == 0 && masterEvent.getLength() == 0) {

			Position[] fragments= getFragments();
			if (fragments.length == 0) {
				// there is no segment in this projection document, thus one must be created
				// need to bypass the usual infrastructure as the new segment/fragment would be of length 0 and thus the segmentation be not well formed
				try {
					Fragment fragment= new Fragment(0, 0);
					fMasterDocument.addPosition(fFragmentsCategory, fragment);
					createSegmentFor(fragment, 0);
				} catch (BadPositionCategoryException x) {
					internalError();
				}
			}
		}

		return isUpdating();
	}

	/**
	 * When called, this projection document is informed about a forthcoming
	 * change of its master document. This projection document checks whether
	 * the master document change affects it and if so informs all document
	 * listeners.
	 *
	 * @param masterEvent the master document event
	 */
	public void masterDocumentAboutToBeChanged(DocumentEvent masterEvent) {
		try {

			boolean assertNotNull= adaptProjectionToMasterChange(masterEvent);
			fSlaveEvent= normalize(masterEvent);
			if (assertNotNull && fSlaveEvent == null)
				internalError();

			fMasterEvent= masterEvent;
			if (fSlaveEvent != null)
				delayedFireDocumentAboutToBeChanged();

		} catch (BadLocationException e) {
			internalError();
		}
	}

	/**
	 * When called, this projection document is informed about a change of its
	 * master document. If this projection document is affected it informs all
	 * of its document listeners.
	 *
	 * @param masterEvent the master document event
	 */
	public void masterDocumentChanged(DocumentEvent masterEvent) {
		if ( !isUpdating() && masterEvent == fMasterEvent) {
			if (fSlaveEvent != null) {
				try {
					getTracker().replace(fSlaveEvent.getOffset(), fSlaveEvent.getLength(), fSlaveEvent.getText());
					fireDocumentChanged(fSlaveEvent);
				} catch (BadLocationException e) {
					internalError();
				}
			} else if (ensureWellFormedSegmentation(masterEvent.getOffset()))
				fMapping.projectionChanged();
		}
	}

	/*
	 * @see org.eclipse.jface.text.AbstractDocument#fireDocumentAboutToBeChanged(org.eclipse.jface.text.DocumentEvent)
	 */
	protected void fireDocumentAboutToBeChanged(DocumentEvent event) {
		fOriginalEvent= event;
		// delay it until there is a notification from the master document
		// at this point, it is expensive to construct the master document information
	}

	/**
	 * Fires the slave document event as about-to-be-changed event to all registered listeners.
	 */
	private void delayedFireDocumentAboutToBeChanged() {
		super.fireDocumentAboutToBeChanged(fSlaveEvent);
	}

	/**
	 * Ignores the given event and sends the semantically equal slave document event instead.
	 *
	 * @param event the event to be ignored
	 */
	protected void fireDocumentChanged(DocumentEvent event) {
		super.fireDocumentChanged(fSlaveEvent);
	}

	/*
	 * @see org.eclipse.jface.text.AbstractDocument#updateDocumentStructures(org.eclipse.jface.text.DocumentEvent)
	 */
	protected void updateDocumentStructures(DocumentEvent event) {
		super.updateDocumentStructures(event);
		ensureWellFormedSegmentation(computeAnchor(event));
		fMapping.projectionChanged();
	}

	private int computeAnchor(DocumentEvent event) {
		if (event instanceof ProjectionDocumentEvent) {
			ProjectionDocumentEvent slave= (ProjectionDocumentEvent) event;
			Object changeType= slave.getChangeType();
			if (ProjectionDocumentEvent.CONTENT_CHANGE == changeType) {
				DocumentEvent master= slave.getMasterEvent();
				if (master != null)
					return master.getOffset();
			} else if (ProjectionDocumentEvent.PROJECTION_CHANGE == changeType) {
				return slave.getMasterOffset();
			}
		}
		return -1;
	}

	private boolean ensureWellFormedSegmentation(int anchorOffset) {
		boolean changed= false;
		Position[] segments= getSegments();
		for (int i= 0; i < segments.length; i++) {
			Segment segment= (Segment) segments[i];
			if (segment.isDeleted() || segment.getLength() == 0) {
				try {
					removePosition(fSegmentsCategory, segment);
					fMasterDocument.removePosition(fFragmentsCategory, segment.fragment);
					changed= true;
				} catch (BadPositionCategoryException e) {
					internalError();
				}
			} else if (i < segments.length - 1) {
				Segment next= (Segment) segments[i + 1];
				if (next.isDeleted() || next.getLength() == 0)
					continue;
				Fragment fragment= segment.fragment;
				if (fragment.getOffset() + fragment.getLength() == next.fragment.getOffset()) {
					// join fragments and their corresponding segments
					segment.setLength(segment.getLength() + next.getLength());
					fragment.setLength(fragment.getLength() + next.fragment.getLength());
					next.delete();
				}
			}
		}

		if (changed && anchorOffset != -1) {
			Position[] changedSegments= getSegments();
			if (changedSegments == null || changedSegments.length == 0) {
				Fragment fragment= new Fragment(anchorOffset, 0);
				try {
					fMasterDocument.addPosition(fFragmentsCategory, fragment);
					createSegmentFor(fragment, 0);
				} catch (BadLocationException e) {
					internalError();
				} catch (BadPositionCategoryException e) {
					internalError();
				}
			}
		}

		return changed;
	}

	/*
	 * @see IDocumentExtension#registerPostNotificationReplace(IDocumentListener, IDocumentExtension.IReplace)
	 */
	public void registerPostNotificationReplace(IDocumentListener owner, IDocumentExtension.IReplace replace) {
		if (!isUpdating())
			throw new UnsupportedOperationException();
		super.registerPostNotificationReplace(owner, replace);
	}

	/**
	 * Sets the auto expand mode for this document.
	 *
	 * @param autoExpandMode <code>true</code> if auto-expanding
	 */
	public void setAutoExpandMode(boolean autoExpandMode) {
		fIsAutoExpanding= autoExpandMode;
	}

	/**
	 * Replaces all master document ranges with the given master document range.
	 *
	 * @param offsetInMaster the offset in the master document
	 * @param lengthInMaster the length in the master document
	 * @throws BadLocationException if the given range of the master document is not valid
	 */
	public void replaceMasterDocumentRanges(int offsetInMaster, int lengthInMaster) throws BadLocationException {
		try {

			ProjectionDocumentEvent event= new ProjectionDocumentEvent(this, 0, fMapping.getImageLength(), fMasterDocument.get(offsetInMaster, lengthInMaster), offsetInMaster, lengthInMaster);
			super.fireDocumentAboutToBeChanged(event);

			Position[] fragments= getFragments();
			for (int i= 0; i < fragments.length; i++) {
				Fragment fragment= (Fragment) fragments[i];
				fMasterDocument.removePosition(fFragmentsCategory, fragment);
				removePosition(fSegmentsCategory, fragment.segment);
			}

			Fragment fragment= new Fragment(offsetInMaster, lengthInMaster);
			Segment segment= new Segment(0, 0);
			segment.fragment= fragment;
			fragment.segment= segment;
			fMasterDocument.addPosition(fFragmentsCategory, fragment);
			addPosition(fSegmentsCategory, segment);

			getTracker().set(fMasterDocument.get(offsetInMaster, lengthInMaster));
			super.fireDocumentChanged(event);

		} catch (BadPositionCategoryException x) {
			internalError();
		}
	}
}
