diff --git a/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/FileBasedChangePackageImpl.java b/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/FileBasedChangePackageImpl.java
index 013fca3..05fdee3 100644
--- a/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/FileBasedChangePackageImpl.java
+++ b/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/FileBasedChangePackageImpl.java
@@ -55,7 +55,6 @@
 import org.eclipse.emf.emfstore.internal.server.model.versioning.impl.persistent.Direction;
 import org.eclipse.emf.emfstore.internal.server.model.versioning.impl.persistent.FileBasedOperationIterable;
 import org.eclipse.emf.emfstore.internal.server.model.versioning.impl.persistent.OperationEmitter;
-import org.eclipse.emf.emfstore.internal.server.model.versioning.impl.persistent.ReadLineCapable;
 import org.eclipse.emf.emfstore.internal.server.model.versioning.impl.persistent.XmlTags;
 import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.AbstractOperation;
 import org.eclipse.emf.emfstore.server.ESCloseableIterable;
@@ -63,6 +62,7 @@
 
 import com.google.common.base.Optional;
 import com.google.common.collect.Iterables;
+import com.google.common.io.Closeables;
 
 /**
  * <!-- begin-user-doc -->
@@ -93,7 +93,7 @@
 	/**
 	 * @generated NOT
 	 */
-	private static final String EMPTY_CHANGE_PACKAGE = XmlTags.XML_HEADER + XmlTags.CHANGE_PACKAGE_START
+	private static final String EMPTY_CHANGE_PACKAGE = XmlTags.XML_HEADER + XmlTags.CHANGE_PACKAGE_START_WITH_NEWLINE
 		+ XmlTags.CHANGE_PACKAGE_END;
 
 	/**
@@ -687,16 +687,15 @@
 	 */
 	public List<AbstractOperation> removeAtEnd(int n) {
 		final List<AbstractOperation> ops = new ArrayList<AbstractOperation>();
-		final OperationEmitter operationEmitter = new OperationEmitter(Direction.Backward);
-		Optional<ReversedLinesFileReader> maybeReversedReader = Optional.absent();
-		int counter = n;
+		final Optional<ReversedLinesFileReader> maybeReversedReader = Optional.absent();
+		RandomAccessFile raf = null;
+		OperationEmitter operationEmitter = null;
 
 		try {
-			final ReversedLinesFileReader reversedReader = new ReversedLinesFileReader(new File(getTempFilePath()));
-			maybeReversedReader = Optional.of(reversedReader);
+			operationEmitter = new OperationEmitter(Direction.Backward, new File(getTempFilePath()));
+			int counter = n;
 			AbstractOperation operation;
-			final ReadLineCapable reader = ReadLineCapable.INSTANCE.create(reversedReader);
-			final Optional<AbstractOperation> maybeOperation = operationEmitter.tryEmit(reader);
+			final Optional<AbstractOperation> maybeOperation = operationEmitter.tryEmit();
 
 			int removedOps = 0;
 			int removedLeafOps = 0;
@@ -710,16 +709,12 @@
 
 			updateCaches(-removedOps, -removedLeafOps);
 
-			// FIXME: reuse ReadLineCapable?
-			final long offset = operationEmitter.getOffset();
-
-			final RandomAccessFile raf = new RandomAccessFile(getTempFilePath(), "rw"); //$NON-NLS-1$
-			final long skip = raf.length() + 1 - offset;
+			raf = new RandomAccessFile(getTempFilePath(), "rw"); //$NON-NLS-1$
+			final long skip = operationEmitter.getOffset();
 			raf.seek(skip);
 			final byte[] bytes = asBytes(XmlTags.NEWLINE + XmlTags.CHANGE_PACKAGE_END);
 			raf.write(bytes);
-			raf.setLength(skip + bytes.length);
-			raf.close();
+			raf.setLength(skip + bytes.length);			
 
 			return ops;
 
@@ -727,12 +722,14 @@
 			// ESException not available
 			throw new IllegalStateException(ex);
 		} finally {
-			if (maybeReversedReader.isPresent()) {
-				try {
-					maybeReversedReader.get().close();
-				} catch (final IOException ex) {
-					ModelUtil.logException(ex);
+			try {
+				Closeables.close(raf, true);
+				Closeables.close(operationEmitter, true);
+				if (maybeReversedReader.isPresent()) {
+					Closeables.close(maybeReversedReader.get(), true);
 				}
+			} catch (final IOException ex) {
+				ModelUtil.logException(ex);
 			}
 		}
 	}
diff --git a/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/persistent/OperationEmitter.java b/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/persistent/OperationEmitter.java
index f056d89..99bbc7f 100644
--- a/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/persistent/OperationEmitter.java
+++ b/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/persistent/OperationEmitter.java
@@ -11,23 +11,33 @@
  ******************************************************************************/
 package org.eclipse.emf.emfstore.internal.server.model.versioning.impl.persistent;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
+import java.io.BufferedReader;
+import java.io.Closeable;
+import java.io.DataInput;
+import java.io.File;
+import java.io.FileReader;
 import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.RandomAccessFile;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
-import org.apache.commons.lang.StringUtils;
+import org.apache.commons.io.input.ReversedLinesFileReader;
 import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.emf.ecore.resource.ResourceSet;
 import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl;
+import org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl;
 import org.eclipse.emf.emfstore.internal.common.model.util.ModelUtil;
 import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.AbstractOperation;
-import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.CreateDeleteOperation;
 
 import com.google.common.base.Optional;
+import com.google.common.collect.Maps;
 
 /**
  * Type for emitting {@link AbstractOperation}s when given an {@link ReadLineCapable} type.
@@ -35,23 +45,67 @@
  * @author emueller
  *
  */
-public class OperationEmitter {
+public class OperationEmitter implements Closeable {
 
-	private static final long NEWLINE_LENGTH = System.getProperty("line.separator").getBytes().length; //$NON-NLS-1$
-
-	private boolean withinOperationsElement;
 	private final Direction direction;
-	private long offset;
+
+	private final File operationsFile;
+
+	private ReadLineCapable reader;
+	private final List<Long> forwardOffsets = new ArrayList<Long>();
+	private final List<Long> backwardsOffsets = new ArrayList<Long>();
+	private int currentOpIndex;
+	private long startOffset;
 
 	/**
 	 * Constructor.
 	 *
 	 * @param direction
 	 *            the {@link Direction} that is used for reading
+	 * @param file
+	 *            the operation file
 	 */
-	public OperationEmitter(Direction direction) {
+	public OperationEmitter(Direction direction, File file) {
 		this.direction = direction;
-		offset = 0;
+		operationsFile = file;
+		determineOperationOffsets();
+		currentOpIndex = direction == Direction.Forward ? 0 : backwardsOffsets.size() - 1;
+		initReader();
+	}
+
+	private void determineOperationOffsets() {
+		try {
+			// TODO: are there any alternative implementations (e.g. Apache)?
+			final OptimizedRandomAccessFile raf = new OptimizedRandomAccessFile(operationsFile, "r"); //$NON-NLS-1$
+			try {
+				String line;
+				while ((line = raf.readLine()) != null) {
+					if (line.contains(XmlTags.CHANGE_PACKAGE_START)) {
+						startOffset = raf.getFilePointer();
+					} else if (line.contains(XmlTags.OPERATIONS_START_TAG)) {
+						forwardOffsets.add(raf.getFilePointer());
+					} else if (line.contains(XmlTags.OPERATIONS_END_TAG)) {
+						backwardsOffsets.add(raf.getFilePointer());
+					}
+				}
+			} finally {
+				raf.close();
+			}
+		} catch (final IOException ex) {
+			ModelUtil.logException(ex);
+		}
+	}
+
+	private void initReader() {
+		try {
+			if (direction == Direction.Forward) {
+				reader = ReadLineCapable.INSTANCE.create(new BufferedReader(new FileReader(operationsFile)));
+			} else {
+				reader = ReadLineCapable.INSTANCE.create(new ReversedLinesFileReader(operationsFile));
+			}
+		} catch (final IOException ex) {
+			ModelUtil.logException(ex);
+		}
 	}
 
 	/**
@@ -60,45 +114,125 @@
 	 * @return the current offset
 	 */
 	public long getOffset() {
-		return offset;
+		if (currentOpIndex < 0) {
+			return startOffset;
+		}
+		return backwardsOffsets.get(currentOpIndex);
+	}
+
+	private void readForward(PipedOutputStream pos) {
+		try {
+			boolean withinOperationsElement = false;
+			final boolean isForwardDir = direction == Direction.Forward;
+			final String closingTag = getClosingTag(isForwardDir);
+			String line = reader.readLine();
+			while (line != null && !line.contains(closingTag)) {
+				if (line.contains(getOpeningTag(isForwardDir))) {
+					withinOperationsElement = true;
+				} else if (withinOperationsElement) {
+					pos.write(line.getBytes());
+				}
+				line = reader.readLine();
+			}
+			if (line != null) {
+				withinOperationsElement = false;
+			}
+		} catch (final IOException ex) {
+			ModelUtil.logException(ex);
+		} finally {
+			try {
+				pos.close();
+			} catch (final IOException ex) {
+				ModelUtil.logException(ex);
+			}
+		}
+	}
+
+	private void readForward(DataInput reader, PipedOutputStream pos) {
+		try {
+			boolean withinOperationsElement = true;
+			final String closingTag = getClosingTag(true);
+			String line = reader.readLine();
+			while (line != null && !line.contains(closingTag)) {
+				if (line.contains(getOpeningTag(true))) {
+					withinOperationsElement = true;
+				} else if (withinOperationsElement && line.length() > 0) {
+					pos.write(line.getBytes());
+				}
+				line = reader.readLine();
+			}
+		} catch (final IOException ex) {
+			ModelUtil.logException(ex);
+		} finally {
+			try {
+				pos.close();
+			} catch (final IOException ex) {
+				ModelUtil.logException(ex);
+			}
+		}
+	}
+
+	private void readBackward(PipedOutputStream pos) {
+
+		if (currentOpIndex < 0) {
+			try {
+				pos.close();
+			} catch (final IOException ex) {
+				ModelUtil.logException(ex);
+			}
+			return;
+		}
+
+		final long offset = forwardOffsets.get(currentOpIndex);
+		currentOpIndex -= 1;
+
+		RandomAccessFile raf = null;
+		try {
+			raf = new RandomAccessFile(operationsFile, "r"); //$NON-NLS-1$
+			raf.skipBytes((int) offset);
+			readForward(raf, pos);
+		} catch (final IOException ex) {
+			ModelUtil.logException(ex);
+		} finally {
+			try {
+				raf.close();
+			} catch (final IOException ex) {
+				ModelUtil.logException(ex);
+			}
+		}
 	}
 
 	/**
-	 * Given a reader, tries to parse an operation and emit it is,
+	 * Tries to parse an operation in the reading directions and emits it,
 	 * if parsing has been successful.
 	 *
-	 * @param reader
-	 *            the reader that is used to de-serialize operations
 	 * @return the successfully parsed operation
 	 * @throws IOException
 	 *             in case reading from the {@link ReadLineCapable} fails
 	 */
-	public Optional<AbstractOperation> tryEmit(ReadLineCapable reader) throws IOException {
-		final List<String> readLines = new ArrayList<String>();
-		withinOperationsElement = false;
-		String line;
-		final boolean isForwardDir = direction == Direction.Forward;
-		while ((line = reader.readLine()) != null && !line.contains(getClosingTag(isForwardDir))) {
-			if (line.contains(getOpeningTag(isForwardDir))) {
-				withinOperationsElement = true;
-			} else if (withinOperationsElement) {
-				readLines.add(line);
+	public Optional<AbstractOperation> tryEmit() throws IOException {
+		final PipedOutputStream pos = new PipedOutputStream();
+		final PipedInputStream pis = new PipedInputStream(pos);
+
+		new Thread(new Runnable() {
+			public void run() {
+				if (direction == Direction.Forward) {
+					readForward(pos);
+				} else {
+					readBackward(pos);
+				}
 			}
-			offset += line.getBytes().length;
-			offset += NEWLINE_LENGTH;
-		}
-		if (line != null) {
-			withinOperationsElement = false;
-			offset += line.getBytes().length;
-		}
-		if (!withinOperationsElement && !readLines.isEmpty()) {
-			if (direction == Direction.Backward) {
-				Collections.reverse(readLines);
-			}
-			return Optional.of(deserialize(StringUtils.join(readLines, StringUtils.EMPTY)));
+		}).start();
+
+		try {
+			return Optional.of(deserialize(pis));
+		} catch (final IOException e) {
+			// e.printStackTrace();
+			return Optional.absent();
+		} finally {
+			pis.close();
 		}
 
-		return Optional.absent();
 	}
 
 	private String getClosingTag(boolean isForward) {
@@ -109,18 +243,25 @@
 		return isForward ? XmlTags.OPERATIONS_START_TAG : XmlTags.OPERATIONS_END_TAG;
 	}
 
-	private AbstractOperation deserialize(final String string) throws IOException {
+	private AbstractOperation deserialize(final PipedInputStream pis) throws IOException {
 		final ResourceSet resourceSet = new ResourceSetImpl();
 		final Resource resource = resourceSet.createResource(URI.createURI("virtualResource.xmi")); //$NON-NLS-1$
-		final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-		outputStream.write(string.getBytes());
-		final ByteArrayInputStream inputStream = new ByteArrayInputStream(outputStream.toByteArray());
-		resource.load(inputStream, ModelUtil.getResourceLoadOptions());
+		((XMLResourceImpl) resource).setIntrinsicIDToEObjectMap(Maps.<String, EObject> newLinkedHashMap());
+		final XMLLoadImpl xmlLoadImpl = new XMLLoadImpl(new XMLHelperImpl());
+		xmlLoadImpl.load((XMLResource) resource, pis, ModelUtil.getResourceLoadOptions());
 		final AbstractOperation operation = (AbstractOperation) resource.getContents().get(0);
-		if (operation instanceof CreateDeleteOperation) {
-			((CreateDeleteOperation) operation).getSubOperations();
-		}
+		// ((XMLResourceImpl) resource).getIntrinsicIDToEObjectMap().clear();
 		return operation;
-
 	}
-}
\ No newline at end of file
+
+	/**
+	 * Closes the emitter.
+	 */
+	public void close() {
+		try {
+			reader.close();
+		} catch (final IOException ex) {
+			ModelUtil.logException(ex);
+		}
+	}
+}
diff --git a/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/persistent/OperationIterator.java b/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/persistent/OperationIterator.java
index 79597dd..f3c3448 100644
--- a/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/persistent/OperationIterator.java
+++ b/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/persistent/OperationIterator.java
@@ -11,13 +11,10 @@
  ******************************************************************************/
 package org.eclipse.emf.emfstore.internal.server.model.versioning.impl.persistent;
 
-import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileReader;
 import java.io.IOException;
 import java.util.Iterator;
 
-import org.apache.commons.io.input.ReversedLinesFileReader;
 import org.apache.commons.lang.NotImplementedException;
 import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.AbstractOperation;
 
@@ -34,7 +31,7 @@
 
 	private Optional<AbstractOperation> operation;
 	private OperationEmitter operationEmitter;
-	private ReadLineCapable reader;
+	// private ReadLineCapable reader;
 	private boolean isInitialized;
 	private final String operationsFilePath;
 	private final Direction direction;
@@ -54,17 +51,7 @@
 	}
 
 	private void init() {
-		operationEmitter = new OperationEmitter(direction);
-		try {
-			if (direction == Direction.Forward) {
-				reader = ReadLineCapable.INSTANCE
-					.create(new BufferedReader(new FileReader(new File(operationsFilePath))));
-			} else {
-				reader = ReadLineCapable.INSTANCE.create(new ReversedLinesFileReader(new File(operationsFilePath)));
-			}
-		} catch (final IOException ex1) {
-			ex1.printStackTrace();
-		}
+		operationEmitter = new OperationEmitter(direction, new File(operationsFilePath));
 		isInitialized = true;
 	}
 
@@ -79,13 +66,14 @@
 			init();
 		}
 		try {
-			operation = operationEmitter.tryEmit(reader);
+			operation = operationEmitter.tryEmit();
 			final boolean hasNext = operation.isPresent();
 			if (!hasNext) {
 				close();
 			}
 			return hasNext;
 		} catch (final IOException ex) {
+			// TODO
 			// replace operations file
 			ex.printStackTrace();
 		}
@@ -120,13 +108,6 @@
 	 * Closes the underlying operations file.
 	 */
 	public void close() {
-		try {
-			if (reader != null) {
-				reader.close();
-			}
-		} catch (final IOException ex) {
-			// TODO
-			ex.printStackTrace();
-		}
+		operationEmitter.close();
 	}
 }
diff --git a/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/persistent/OptimizedRandomAccessFile.java b/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/persistent/OptimizedRandomAccessFile.java
new file mode 100644
index 0000000..3ab37e6
--- /dev/null
+++ b/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/persistent/OptimizedRandomAccessFile.java
@@ -0,0 +1,1088 @@
+/*
+ * The MIT License
+ * Copyright 2013 Joos Kiener <Joos.Kiener@gmail.com>.
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package org.eclipse.emf.emfstore.internal.server.model.versioning.impl.persistent;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.io.UTFDataFormatException;
+
+/**
+ * <p>
+ * Wrapper of {@link java.io.RandomAccessFile
+ * <code>RandomAccessFile</code>} that has an readLine method performing similar
+ * to {@link java.io.BufferedReader#readLine()} while keeping the random access
+ * functionality.
+ * </p>
+ *
+ * <p>
+ * {@link java.io.RandomAccessFile#readLine()} is very slow as it reads a
+ * file byte by byte. This here will perform 2 orders of magnitude faster.
+ * For thread-safety all read and write methods are synchronized.
+ * </p>
+ * </p>
+ * If the underlying {@link java.nio.channels.FileChannel
+ * <code>FileChannel</code>} is manipulated, the behavior is unpredictable.
+ * Therefore this class does not expose the <code>getFileChannel()</code> method
+ * of <code>RandomAccessFile</code>.
+ * </p>
+ *
+ * @author Joos Kiener <Joos.Kiener@gmail.com>
+ */
+public class OptimizedRandomAccessFile {
+
+	private static final int BUFFER_SIZE = 8192;
+	private static int defaultExpectedLineLength = 80;
+	private final RandomAccessFile raf;
+	private Long actualFilePointer;
+	private final char[] charBuffer;
+	private int nChars, nextChar;
+	private final int bufferSize;
+	private long lastOffset;
+	private boolean skipLF;
+
+	/**
+	 * see {@link RandomAccessFile#RandomAccessFile(String,String)}
+	 *
+	 * @param name path to the text file
+	 * @param mode r, rw, rws, rwd
+	 * @throws FileNotFoundException
+	 */
+	public OptimizedRandomAccessFile(String name, String mode) throws FileNotFoundException {
+		this(name != null ? new File(name) : null, mode);
+	}
+
+	/**
+	 *
+	 * see {@link RandomAccessFile#RandomAccessFile(File,String)}
+	 *
+	 * @param file
+	 * @param mode
+	 * @throws FileNotFoundException
+	 */
+	public OptimizedRandomAccessFile(File file, String mode) throws FileNotFoundException {
+		raf = new RandomAccessFile(file, mode);
+		actualFilePointer = null;
+		bufferSize = BUFFER_SIZE;
+		charBuffer = new char[bufferSize];
+	}
+
+	/**
+	 * <p>
+	 * Returns the opaque file descriptor object associated with this
+	 * stream.
+	 * </p>
+	 *
+	 * @return the file descriptor object associated with this stream.
+	 * @exception IOException if an I/O error occurs.
+	 * @see java.io.FileDescriptor
+	 */
+	public final FileDescriptor getFD() throws IOException {
+		return raf.getFD();
+	}
+
+	/**
+	 * Reads a byte of data from this file. The byte is returned as an integer
+	 * in the range 0 to 255 (
+	 * <code>0x00-0x0ff</code>). This method behaves similar to the
+	 * {@link java.io.BufferedReader#read()} method of
+	 * <code>BufferedReader</code>.
+	 *
+	 * @return the next byte of data, or <code>-1</code> if the end of the file
+	 *         has been reached.
+	 * @exception IOException if an I/O error occurs. Not thrown if end-of-file
+	 *                has been reached.
+	 */
+	public synchronized int read() throws IOException {
+		// resetPosition();
+		for (;;) {
+			if (nextChar >= nChars) {
+				fill();
+				if (nextChar >= nChars) {
+					return -1;
+				}
+			}
+			if (skipLF) {
+				skipLF = false;
+				if (charBuffer[nextChar] == '\n') {
+					nextChar++;
+					continue;
+				}
+			}
+			final int result = charBuffer[nextChar++];
+			actualFilePointer++;
+			return result;
+		}
+	}
+
+	/**
+	 * Reads characters into a portion of an array, reading from the underlying
+	 * stream if necessary.
+	 */
+	private int read1(byte[] cbuf, int off, int len) throws IOException {
+		if (nextChar >= nChars) {
+			/*
+			 * If the requested length is at least as large as the buffer and
+			 * if line feeds are not being skipped, do not bother to copy the
+			 * characters into the local buffer. In this way buffered streams
+			 * will cascade harmlessly.
+			 */
+			if (len >= charBuffer.length && !skipLF) {
+				actualFilePointer = null;
+				return raf.read(cbuf, off, len);
+			}
+			fill();
+		}
+		if (nextChar >= nChars) {
+			return -1;
+		}
+		if (skipLF) {
+			skipLF = false;
+			if (charBuffer[nextChar] == '\n') {
+				nextChar++;
+				if (nextChar >= nChars) {
+					fill();
+				}
+				if (nextChar >= nChars) {
+					return -1;
+				}
+			}
+		}
+		final int n = Math.min(len, nChars - nextChar);
+		for (int i = 0; i < n; i++) {
+			cbuf[off + i] = (byte) charBuffer[nextChar + i];
+		}
+		// System.arraycopy(charBuffer, nextChar, cbuf, off, n);
+		nextChar += n;
+		actualFilePointer += n;
+		return n;
+	}
+
+	/**
+	 * Reads up to
+	 * <code>len</code> bytes of data from this file into an array of bytes.
+	 * This method behaves similar to the
+	 * {@link java.io.BufferedReader#read(byte[],int,int)} method of
+	 * <code>BufferedReader</code>.
+	 *
+	 * @param b the buffer into which the data is read.
+	 * @param off the start offset in array <code>b</code> at which the data is
+	 *            written.
+	 * @param len the maximum number of bytes read.
+	 * @return the total number of bytes read into the buffer, or
+	 *         <code>-1</code> if there is no more data because the end of the file has
+	 *         been reached.
+	 * @exception IOException If the first byte cannot be read for any reason
+	 *                other than end of file, or if the random access file has been closed, or
+	 *                if some other I/O error occurs.
+	 * @exception NullPointerException If <code>b</code> is <code>null</code>.
+	 * @exception IndexOutOfBoundsException If <code>off</code> is negative,
+	 *                <code>len</code> is negative, or <code>len</code> is greater than
+	 *                <code>b.length - off</code>
+	 */
+	public synchronized int read(byte b[], int off, int len) throws IOException {
+		// resetPosition();
+		if (off < 0 || off > b.length || len < 0 || off + len > b.length || off + len < 0) {
+			throw new IndexOutOfBoundsException();
+		} else if (len == 0) {
+			return 0;
+		}
+
+		int n = read1(b, off, len);
+		if (n <= 0) {
+			return n;
+		}
+		while (n < len) {
+			final int n1 = read1(b, off + n, len - n);
+			if (n1 <= 0) {
+				break;
+			}
+			n += n1;
+		}
+		return n;
+		// return raf.read(b, off, len);
+	}
+
+	/**
+	 * Reads up to
+	 * <code>b.length</code> bytes of data from this file into an array of
+	 * bytes. This method behaves similar to the
+	 * {@link java.io.BufferedReader#read(byte[])} method of
+	 * <code>BufferedReader</code>.
+	 *
+	 * @param b the buffer into which the data is read.
+	 * @return the total number of bytes read into the buffer, or
+	 *         <code>-1</code> if there is no more data because the end of this file has
+	 *         been reached.
+	 * @exception IOException If the first byte cannot be read for any reason
+	 *                other than end of file, or if the random access file has been closed, or
+	 *                if some other I/O error occurs.
+	 * @exception NullPointerException If <code>b</code> is <code>null</code>.
+	 */
+	public synchronized int read(byte b[]) throws IOException {
+		return read(b, 0, b.length);
+	}
+
+	/**
+	 * Reads
+	 * <code>b.length</code> bytes from this file into the byte array, starting
+	 * at the current file pointer. This method reads repeatedly from the file
+	 * until the requested number of bytes are read. This method blocks until
+	 * the requested number of bytes are read, the end of the stream is
+	 * detected, or an exception is thrown.
+	 *
+	 * @param b the buffer into which the data is read.
+	 * @exception EOFException if this file reaches the end before reading all
+	 *                the bytes.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final void readFully(byte b[]) throws IOException {
+		resetPosition();
+		raf.readFully(b);
+	}
+
+	/**
+	 * Reads exactly
+	 * <code>len</code> bytes from this file into the byte array, starting at
+	 * the current file pointer. This method reads repeatedly from the file
+	 * until the requested number of bytes are read. This method blocks until
+	 * the requested number of bytes are read, the end of the stream is
+	 * detected, or an exception is thrown.
+	 *
+	 * @param b the buffer into which the data is read.
+	 * @param off the start offset of the data.
+	 * @param len the number of bytes to read.
+	 * @exception EOFException if this file reaches the end before reading all
+	 *                the bytes.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final void readFully(byte b[], int off, int len) throws IOException {
+		resetPosition();
+		raf.readFully(b, off, len);
+	}
+
+	/**
+	 * Attempts to skip over
+	 * <code>n</code> bytes of input discarding the skipped bytes.
+	 * <p>
+	 *
+	 * This method may skip over some smaller number of bytes, possibly zero.
+	 * This may result from any of a number of conditions; reaching end of file
+	 * before
+	 * <code>n</code> bytes have been skipped is only one possibility. This
+	 * method never throws an
+	 * <code>EOFException</code>. The actual number of bytes skipped is
+	 * returned. If
+	 * <code>n</code> is negative, no bytes are skipped.
+	 *
+	 * @param n the number of bytes to be skipped.
+	 * @return the actual number of bytes skipped.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized int skipBytes(int n) throws IOException {
+
+		if (n < 0L) {
+			throw new IllegalArgumentException("skip value is negative");
+		}
+
+		int r = n;
+		while (r > 0) {
+			if (nextChar >= nChars) {
+				fill();
+			}
+			if (nextChar >= nChars) /* EOF */ {
+				break;
+			}
+			if (skipLF) {
+				skipLF = false;
+				if (charBuffer[nextChar] == '\n') {
+					nextChar++;
+				}
+			}
+			final long d = nChars - nextChar;
+			if (r <= d) {
+				nextChar += r;
+				r = 0;
+				break;
+			} else {
+				r -= d;
+				nextChar = nChars;
+			}
+		}
+		final int skipped = n - r;
+		actualFilePointer += skipped;
+		return skipped;
+
+		// resetPosition();
+		// return raf.skipBytes(n);
+	}
+
+	// 'Write' primitives
+	/**
+	 * Writes the specified byte to this file. The write starts at the current
+	 * file pointer.
+	 *
+	 * @param b the <code>byte</code> to be written.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized void write(int b) throws IOException {
+		resetPosition();
+		raf.write(b);
+	}
+
+	/**
+	 * Writes
+	 * <code>b.length</code> bytes from the specified byte array to this file,
+	 * starting at the current file pointer.
+	 *
+	 * @param b the data.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized void write(byte b[]) throws IOException {
+		resetPosition();
+		raf.write(b, 0, b.length);
+	}
+
+	/**
+	 * Writes
+	 * <code>len</code> bytes from the specified byte array starting at offset
+	 * <code>off</code> to this file.
+	 *
+	 * @param b the data.
+	 * @param off the start offset in the data.
+	 * @param len the number of bytes to write.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized void write(byte b[], int off, int len) throws IOException {
+		resetPosition();
+		raf.write(b, off, len);
+	}
+
+	// 'Random access' stuff
+	/**
+	 * Returns the current offset in this file.
+	 *
+	 * @return the offset from the beginning of the file, in bytes, at which the
+	 *         next read or write occurs.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized long getFilePointer() throws IOException {
+		if (actualFilePointer == null) {
+			return raf.getFilePointer();
+		} else {
+			return actualFilePointer;
+		}
+	}
+
+	/**
+	 * Sets the file-pointer offset, measured from the beginning of this file,
+	 * at which the next read or write occurs. The offset may be set beyond the
+	 * end of the file. Setting the offset beyond the end of the file does not
+	 * change the file length. The file length will change only by writing after
+	 * the offset has been set beyond the end of the file.
+	 *
+	 * @param pos the offset position, measured in bytes from the beginning of
+	 *            the file, at which to set the file pointer.
+	 * @exception IOException if <code>pos</code> is less than <code>0</code> or
+	 *                if an I/O error occurs.
+	 */
+	public synchronized void seek(long pos) throws IOException {
+		actualFilePointer = null;
+		resetPosition();
+		raf.seek(pos);
+	}
+
+	/**
+	 * Returns the length of this file.
+	 *
+	 * @return the length of this file, measured in bytes.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized long length() throws IOException {
+		return raf.length();
+	}
+
+	/**
+	 * Sets the length of this file.
+	 *
+	 * <p>
+	 * If the present length of the file as returned by the
+	 * <code>length</code> method is greater than the
+	 * <code>newLength</code> argument then the file will be truncated. In this
+	 * case, if the file offset as returned by the
+	 * <code>getFilePointer</code> method is greater than
+	 * <code>newLength</code> then after this method returns the offset will be
+	 * equal to
+	 * <code>newLength</code>.
+	 *
+	 * <p>
+	 * If the present length of the file as returned by the
+	 * <code>length</code> method is smaller than the
+	 * <code>newLength</code> argument then the file will be extended. In this
+	 * case, the contents of the extended portion of the file are not defined.
+	 *
+	 * @param newLength The desired length of the file
+	 * @exception IOException If an I/O error occurs
+	 * @since 1.2
+	 */
+	public synchronized void setLength(long newLength) throws IOException {
+		if (newLength < raf.length()) {
+			resetPosition();
+		}
+		raf.setLength(newLength);
+	}
+
+	/**
+	 * Closes this random access file stream and releases any system resources
+	 * associated with the stream. A closed random access file cannot perform
+	 * input or output operations and cannot be reopened.
+	 *
+	 * <p>
+	 * If this file has an associated channel then the channel is closed as
+	 * well.
+	 *
+	 * @exception IOException if an I/O error occurs.
+	 *
+	 * @revised 1.4
+	 * @spec JSR-51
+	 */
+	public void close() throws IOException {
+		raf.close();
+	}
+
+	//
+	// Some "reading/writing Java data types" methods stolen from
+	// DataInputStream and DataOutputStream.
+	//
+	/**
+	 * Reads a
+	 * <code>boolean</code> from this file. This method reads a single byte from
+	 * the file, starting at the current file pointer. A value of
+	 * <code>0</code> represents
+	 * <code>false</code>. Any other value represents
+	 * <code>true</code>. This method blocks until the byte is read, the end of
+	 * the stream is detected, or an exception is thrown.
+	 *
+	 * @return the <code>boolean</code> value read.
+	 * @exception EOFException if this file has reached the end.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final boolean readBoolean() throws IOException {
+		resetPosition();
+		return raf.readBoolean();
+	}
+
+	/**
+	 * Reads a signed eight-bit value from this file. This method reads a byte
+	 * from the file, starting from the current file pointer. If the byte read
+	 * is
+	 * <code>b</code>, where
+	 * <code>0&nbsp;&lt;=&nbsp;b&nbsp;&lt;=&nbsp;255</code>, then the result is:
+	 * null null null null null null null null null null null null null null <blockquote>
+	 * 
+	 * <pre>
+	 * (byte) (b)
+	 * </pre>
+	 * 
+	 * </blockquote>
+	 * <p>
+	 * This method blocks until the byte is read, the
+	 * end of the stream is detected, or an exception is thrown.
+	 *
+	 * @return the next byte of this file as a signed eight-bit
+	 *         <code>byte</code>.
+	 * @exception EOFException if this file has reached the end.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final byte readByte() throws IOException {
+		resetPosition();
+		return raf.readByte();
+	}
+
+	/**
+	 * Reads an unsigned eight-bit number from this file. This method reads a
+	 * byte from this file, starting at the current file pointer, and returns
+	 * that byte.
+	 * <p>
+	 * This method blocks until the byte is read, the end of the
+	 * stream is detected, or an exception is thrown.
+	 *
+	 * @return the next byte of this file, interpreted as an unsigned eight-bit
+	 *         number.
+	 * @exception EOFException if this file has reached the end.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final int readUnsignedByte() throws IOException {
+		resetPosition();
+		return raf.readUnsignedByte();
+	}
+
+	/**
+	 * Reads a signed 16-bit number from this file. The method reads two bytes
+	 * from this file, starting at the current file pointer. If the two bytes
+	 * read, in order, are
+	 * <code>b1</code> and
+	 * <code>b2</code>, where each of the two values is between
+	 * <code>0</code> and
+	 * <code>255</code>, inclusive, then the result is equal to: null null null
+	 * null null null null null null null null null null null <blockquote>
+	 * 
+	 * <pre>
+	 * (short) ((b1 &lt;&lt; 8) | b2)
+	 * </pre>
+	 * 
+	 * </blockquote>
+	 * <p>
+	 * This method blocks until the two bytes are read,
+	 * the end of the stream is detected, or an exception is thrown.
+	 *
+	 * @return the next two bytes of this file, interpreted as a signed 16-bit
+	 *         number.
+	 * @exception EOFException if this file reaches the end before reading two
+	 *                bytes.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final short readShort() throws IOException {
+		resetPosition();
+		return raf.readShort();
+	}
+
+	/**
+	 * Reads an unsigned 16-bit number from this file. This method reads two
+	 * bytes from the file, starting at the current file pointer. If the bytes
+	 * read, in order, are
+	 * <code>b1</code> and
+	 * <code>b2</code>, where
+	 * <code>0&nbsp;&lt;=&nbsp;b1, b2&nbsp;&lt;=&nbsp;255</code>, then the
+	 * result is equal to: null null null null null null null null null null
+	 * null null null null <blockquote>
+	 * 
+	 * <pre>
+	 * (b1 &lt;&lt; 8) | b2
+	 * </pre>
+	 * 
+	 * </blockquote>
+	 * <p>
+	 * This method blocks until the two bytes are read,
+	 * the end of the stream is detected, or an exception is thrown.
+	 *
+	 * @return the next two bytes of this file, interpreted as an unsigned
+	 *         16-bit integer.
+	 * @exception EOFException if this file reaches the end before reading two
+	 *                bytes.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final int readUnsignedShort() throws IOException {
+		resetPosition();
+		return raf.readUnsignedShort();
+	}
+
+	/**
+	 * Reads a character from this file. This method reads two bytes from the
+	 * file, starting at the current file pointer. If the bytes read, in order,
+	 * are
+	 * <code>b1</code> and
+	 * <code>b2</code>, where
+	 * <code>0&nbsp;&lt;=&nbsp;b1,&nbsp;b2&nbsp;&lt;=&nbsp;255</code>, then the
+	 * result is equal to: null null null null null null null null null null
+	 * null null null null <blockquote>
+	 * 
+	 * <pre>
+	 * (char) ((b1 &lt;&lt; 8) | b2)
+	 * </pre>
+	 * 
+	 * </blockquote>
+	 * <p>
+	 * This method blocks until the two bytes are read,
+	 * the end of the stream is detected, or an exception is thrown.
+	 *
+	 * @return the next two bytes of this file, interpreted as a
+	 *         <code>char</code>.
+	 * @exception EOFException if this file reaches the end before reading two
+	 *                bytes.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final char readChar() throws IOException {
+		resetPosition();
+		return raf.readChar();
+	}
+
+	/**
+	 * Reads a signed 32-bit integer from this file. This method reads 4 bytes
+	 * from the file, starting at the current file pointer. If the bytes read,
+	 * in order, are
+	 * <code>b1</code>,
+	 * <code>b2</code>,
+	 * <code>b3</code>, and
+	 * <code>b4</code>, where
+	 * <code>0&nbsp;&lt;=&nbsp;b1, b2, b3, b4&nbsp;&lt;=&nbsp;255</code>, then
+	 * the result is equal to: null null null null null null null null null null
+	 * null null null null <blockquote>
+	 * 
+	 * <pre>
+	 * (b1 &lt;&lt; 24) | (b2 &lt;&lt; 16) + (b3 &lt;&lt; 8) + b4
+	 * </pre>
+	 * 
+	 * </blockquote>
+	 * <p>
+	 * This method blocks until the four bytes are read,
+	 * the end of the stream is detected, or an exception is thrown.
+	 *
+	 * @return the next four bytes of this file, interpreted as an
+	 *         <code>int</code>.
+	 * @exception EOFException if this file reaches the end before reading four
+	 *                bytes.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final int readInt() throws IOException {
+		resetPosition();
+		return raf.readInt();
+	}
+
+	/**
+	 * Reads a signed 64-bit integer from this file. This method reads eight
+	 * bytes from the file, starting at the current file pointer. If the bytes
+	 * read, in order, are
+	 * <code>b1</code>,
+	 * <code>b2</code>,
+	 * <code>b3</code>,
+	 * <code>b4</code>,
+	 * <code>b5</code>,
+	 * <code>b6</code>,
+	 * <code>b7</code>, and
+	 * <code>b8,</code> where: null null null null null null null null null null
+	 * null null null null <blockquote>
+	 * 
+	 * <pre>
+	 *     0 &lt;= b1, b2, b3, b4, b5, b6, b7, b8 &lt;=255,
+	 * </pre>
+	 * 
+	 * </blockquote>
+	 * <p>
+	 * then the result is equal to: null null null null
+	 * null null null null null null null null null null
+	 * <p>
+	 * <blockquote>
+	 * 
+	 * <pre>
+	 * ((long) b1 &lt;&lt; 56) + ((long) b2 &lt;&lt; 48) + ((long) b3 &lt;&lt; 40) + ((long) b4 &lt;&lt; 32) + ((long) b5 &lt;&lt; 24)
+	 * 	+ ((long) b6 &lt;&lt; 16) + ((long) b7 &lt;&lt; 8) + b8
+	 * </pre>
+	 * 
+	 * </blockquote>
+	 * <p>
+	 * This method blocks until the eight bytes are
+	 * read, the end of the stream is detected, or an exception is thrown.
+	 *
+	 * @return the next eight bytes of this file, interpreted as a
+	 *         <code>long</code>.
+	 * @exception EOFException if this file reaches the end before reading eight
+	 *                bytes.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final long readLong() throws IOException {
+		resetPosition();
+		return raf.readLong();
+	}
+
+	/**
+	 * Reads a
+	 * <code>float</code> from this file. This method reads an
+	 * <code>int</code> value, starting at the current file pointer, as if by
+	 * the
+	 * <code>readInt</code> method and then converts that
+	 * <code>int</code> to a
+	 * <code>float</code> using the
+	 * <code>intBitsToFloat</code> method in class
+	 * <code>Float</code>.
+	 * <p>
+	 * This method blocks until the four bytes are read,
+	 * the end of the stream is detected, or an exception is thrown.
+	 *
+	 * @return the next four bytes of this file, interpreted as a
+	 *         <code>float</code>.
+	 * @exception EOFException if this file reaches the end before reading four
+	 *                bytes.
+	 * @exception IOException if an I/O error occurs.
+	 * @see java.io.RandomAccessFile#readInt()
+	 * @see java.lang.Float#intBitsToFloat(int)
+	 */
+	public synchronized final float readFloat() throws IOException {
+		resetPosition();
+		return raf.readFloat();
+	}
+
+	/**
+	 * Reads a
+	 * <code>double</code> from this file. This method reads a
+	 * <code>long</code> value, starting at the current file pointer, as if by
+	 * the
+	 * <code>readLong</code> method and then converts that
+	 * <code>long</code> to a
+	 * <code>double</code> using the
+	 * <code>longBitsToDouble</code> method in class
+	 * <code>Double</code>.
+	 * <p>
+	 * This method blocks until the eight bytes are
+	 * read, the end of the stream is detected, or an exception is thrown.
+	 *
+	 * @return the next eight bytes of this file, interpreted as a
+	 *         <code>double</code>.
+	 * @exception EOFException if this file reaches the end before reading eight
+	 *                bytes.
+	 * @exception IOException if an I/O error occurs.
+	 * @see java.io.RandomAccessFile#readLong()
+	 * @see java.lang.Double#longBitsToDouble(long)
+	 */
+	public synchronized final double readDouble() throws IOException {
+		resetPosition();
+		return raf.readDouble();
+	}
+
+	/**
+	 * <p>
+	 * Read the file line by line omitting the line separator.
+	 * </p>
+	 * <p>
+	 * see
+	 * {@link java.io.RandomAccessFile#readLine() readLine()} and see
+	 * {@link java.io.BufferedReader#readLine(boolean) readLine(boolean ignoreLF)}.
+	 * <p>
+	 *
+	 * <p>
+	 * Subsequent calls of this method are buffered. If certain other
+	 * methods that are affected by the current position of the reader in the
+	 * file is called after this method, the position is set to the start of the
+	 * next line and the buffer is invalidated.
+	 * </p>
+	 *
+	 * <p>
+	 * This method is copied from
+	 * {@link java.io.BufferedReader BufferedReader} with minor changes like
+	 * tracking position (offset) were next line starts.
+	 * </p>
+	 *
+	 * @return the next line of text from this file, or null if end of file is
+	 *         encountered before even one byte is read.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final String readLine(boolean ignoreLF) throws IOException {
+
+		StringBuilder s = null;
+		int startChar;
+		int separatorIndex = 0;
+
+		boolean omitLF = ignoreLF || skipLF;
+
+		bufferLoop: for (;;) {
+
+			if (nextChar >= nChars) {
+				fill();
+			}
+			if (nextChar >= nChars) { /* EOF */
+				if (s != null && s.length() > 0) {
+					// EOF -> hence no need to adjust position in file
+					// changed by fill()
+					return s.toString();
+				} else {
+					return null;
+				}
+			}
+			boolean eol = false;
+			char c = 0;
+			int i;
+
+			/* Skip a leftover '\n', if necessary */
+			if (omitLF && charBuffer[nextChar] == '\n') {
+				nextChar++;
+			}
+			skipLF = false;
+			omitLF = false;
+
+			charLoop: for (i = nextChar; i < nChars; i++) {
+				c = charBuffer[i];
+				if (c == '\n' || c == '\r') {
+					eol = true;
+					break charLoop;
+				}
+			}
+
+			startChar = nextChar;
+			nextChar = i;
+
+			if (eol) {
+				String str;
+				if (s == null) {
+					str = new String(charBuffer, startChar, i - startChar);
+				} else {
+					s.append(charBuffer, startChar, i - startChar);
+					str = s.toString();
+				}
+				nextChar++;
+				if (c == '\r') {
+					skipLF = true;
+					if (nextChar >= nChars) {
+						fill();
+					}
+					if (charBuffer[nextChar] == '\n') {
+						separatorIndex = 1;
+					}
+				}
+				actualFilePointer = lastOffset + nextChar + separatorIndex;
+				return str;
+			}
+
+			if (s == null) {
+				s = new StringBuilder(defaultExpectedLineLength);
+			}
+			s.append(charBuffer, startChar, i - startChar);
+		}
+	}
+
+	/**
+	 * see {@link #readLine(boolean) readLine(boolean ignoreLF)}
+	 *
+	 * @return
+	 * @throws IOException
+	 */
+	public synchronized String readLine() throws IOException {
+		return readLine(false);
+	}
+
+	private void fill() throws IOException {
+
+		lastOffset = raf.getFilePointer();
+		actualFilePointer = lastOffset;
+		final byte[] buffer = new byte[bufferSize];
+		final int n = raf.read(buffer);
+		if (n > 0) {
+			nChars = n;
+			nextChar = 0;
+		}
+		for (int i = 0; i < buffer.length; i++) {
+			charBuffer[i] = (char) buffer[i];
+		}
+	}
+
+	/**
+	 * Reads in a string from this file. The string has been encoded using a <a
+	 * href="DataInput.html#modified-utf-8">modified UTF-8</a> format.
+	 * <p>
+	 * The
+	 * first two bytes are read, starting from the current file pointer, as if
+	 * by
+	 * <code>readUnsignedShort</code>. This value gives the number of following
+	 * bytes that are in the encoded string, not the length of the resulting
+	 * string. The following bytes are then interpreted as bytes encoding
+	 * characters in the modified UTF-8 format and are converted into
+	 * characters.
+	 * <p>
+	 * This method blocks until all the bytes are read, the end
+	 * of the stream is detected, or an exception is thrown.
+	 *
+	 * @return a Unicode string.
+	 * @exception EOFException if this file reaches the end before reading all
+	 *                the bytes.
+	 * @exception IOException if an I/O error occurs.
+	 * @exception UTFDataFormatException if the bytes do not represent valid
+	 *                modified UTF-8 encoding of a Unicode string.
+	 * @see java.io.RandomAccessFile#readUnsignedShort()
+	 */
+	public synchronized final String readUTF() throws IOException {
+		resetPosition();
+		return raf.readUTF();
+	}
+
+	/**
+	 * Writes a
+	 * <code>boolean</code> to the file as a one-byte value. The value
+	 * <code>true</code> is written out as the value
+	 * <code>(byte)1</code>; the value
+	 * <code>false</code> is written out as the value
+	 * <code>(byte)0</code>. The write starts at the current position of the
+	 * file pointer.
+	 *
+	 * @param v a <code>boolean</code> value to be written.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final void writeBoolean(boolean v) throws IOException {
+		resetPosition();
+		raf.writeBoolean(v);
+	}
+
+	/**
+	 * Writes a
+	 * <code>byte</code> to the file as a one-byte value. The write starts at
+	 * the current position of the file pointer.
+	 *
+	 * @param v a <code>byte</code> value to be written.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final void writeByte(int v) throws IOException {
+		resetPosition();
+		raf.writeByte(v);
+	}
+
+	/**
+	 * Writes a
+	 * <code>short</code> to the file as two bytes, high byte first. The write
+	 * starts at the current position of the file pointer.
+	 *
+	 * @param v a <code>short</code> to be written.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final void writeShort(int v) throws IOException {
+		resetPosition();
+		raf.writeShort(v);
+	}
+
+	/**
+	 * Writes a
+	 * <code>char</code> to the file as a two-byte value, high byte first. The
+	 * write starts at the current position of the file pointer.
+	 *
+	 * @param v a <code>char</code> value to be written.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final void writeChar(int v) throws IOException {
+		resetPosition();
+		raf.writeChar(v);
+	}
+
+	/**
+	 * Writes an
+	 * <code>int</code> to the file as four bytes, high byte first. The write
+	 * starts at the current position of the file pointer.
+	 *
+	 * @param v an <code>int</code> to be written.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final void writeInt(int v) throws IOException {
+		resetPosition();
+		raf.writeInt(v);
+	}
+
+	/**
+	 * Writes a
+	 * <code>long</code> to the file as eight bytes, high byte first. The write
+	 * starts at the current position of the file pointer.
+	 *
+	 * @param v a <code>long</code> to be written.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final void writeLong(long v) throws IOException {
+		resetPosition();
+		raf.writeLong(v);
+	}
+
+	/**
+	 * Converts the float argument to an
+	 * <code>int</code> using the
+	 * <code>floatToIntBits</code> method in class
+	 * <code>Float</code>, and then writes that
+	 * <code>int</code> value to the file as a four-byte quantity, high byte
+	 * first. The write starts at the current position of the file pointer.
+	 *
+	 * @param v a <code>float</code> value to be written.
+	 * @exception IOException if an I/O error occurs.
+	 * @see java.lang.Float#floatToIntBits(float)
+	 */
+	public synchronized final void writeFloat(float v) throws IOException {
+		resetPosition();
+		raf.writeFloat(v);
+	}
+
+	/**
+	 * Converts the double argument to a
+	 * <code>long</code> using the
+	 * <code>doubleToLongBits</code> method in class
+	 * <code>Double</code>, and then writes that
+	 * <code>long</code> value to the file as an eight-byte quantity, high byte
+	 * first. The write starts at the current position of the file pointer.
+	 *
+	 * @param v a <code>double</code> value to be written.
+	 * @exception IOException if an I/O error occurs.
+	 * @see java.lang.Double#doubleToLongBits(double)
+	 */
+	public synchronized final void writeDouble(double v) throws IOException {
+		resetPosition();
+		raf.writeDouble(v);
+	}
+
+	/**
+	 * Writes the string to the file as a sequence of bytes. Each character in
+	 * the string is written out, in sequence, by discarding its high eight
+	 * bits. The write starts at the current position of the file pointer.
+	 *
+	 * @param s a string of bytes to be written.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final void writeBytes(String s) throws IOException {
+		resetPosition();
+		raf.writeBytes(s);
+	}
+
+	/**
+	 * Writes a string to the file as a sequence of characters. Each character
+	 * is written to the data output stream as if by the
+	 * <code>writeChar</code> method. The write starts at the current position
+	 * of the file pointer.
+	 *
+	 * @param s a <code>String</code> value to be written.
+	 * @exception IOException if an I/O error occurs.
+	 * @see java.io.RandomAccessFile#writeChar(int)
+	 */
+	public synchronized final void writeChars(String s) throws IOException {
+		resetPosition();
+		raf.writeChars(s);
+	}
+
+	/**
+	 * Writes a string to the file using <a
+	 * href="DataInput.html#modified-utf-8">modified UTF-8</a> encoding in a
+	 * machine-independent manner.
+	 * <p>
+	 * First, two bytes are written to the file,
+	 * starting at the current file pointer, as if by the
+	 * <code>writeShort</code> method giving the number of bytes to follow. This
+	 * value is the number of bytes actually written out, not the length of the
+	 * string. Following the length, each character of the string is output, in
+	 * sequence, using the modified UTF-8 encoding for each character.
+	 *
+	 * @param str a string to be written.
+	 * @exception IOException if an I/O error occurs.
+	 */
+	public synchronized final void writeUTF(String str) throws IOException {
+		resetPosition();
+		raf.writeUTF(str);
+	}
+
+	private void resetPosition() throws IOException {
+		if (actualFilePointer != null) {
+			raf.seek(actualFilePointer);
+			actualFilePointer = null;
+		}
+		nChars = 0;
+		nextChar = 0;
+	}
+}
\ No newline at end of file
diff --git a/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/persistent/XmlTags.java b/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/persistent/XmlTags.java
index ee74dfd..f46efbc 100644
--- a/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/persistent/XmlTags.java
+++ b/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/impl/persistent/XmlTags.java
@@ -36,8 +36,12 @@
 	 * Change package opening tag.
 	 */
 	public static final String CHANGE_PACKAGE_START = "<org.eclipse.emf.emfstore.internal.server.model.versioning:ChangePackage " //$NON-NLS-1$
-		+ "xmi:version=\"2.0\" xmlns:xmi=\"http://www.omg.org/XMI\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:org.eclipse.emf.emfstore.internal.server.model.versioning=\"http://eclipse.org/emf/emfstore/server/model/versioning\" xmlns:org.eclipse.emf.emfstore.internal.server.model.versioning.operations=\"http://eclipse.org/emf/emfstore/server/model/versioning/operations\">" //$NON-NLS-1$
-		+ NEWLINE;
+		+ "xmi:version=\"2.0\" xmlns:xmi=\"http://www.omg.org/XMI\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:org.eclipse.emf.emfstore.internal.server.model.versioning=\"http://eclipse.org/emf/emfstore/server/model/versioning\" xmlns:org.eclipse.emf.emfstore.internal.server.model.versioning.operations=\"http://eclipse.org/emf/emfstore/server/model/versioning/operations\">"; //$NON-NLS-1$
+
+	/**
+	 * Change package opening tag with newline.
+	 */
+	public static final String CHANGE_PACKAGE_START_WITH_NEWLINE = CHANGE_PACKAGE_START + NEWLINE;
 
 	/**
 	 * Change package closing tag.
