Bug 487834 - ChangePackageEnvelope should be based on List of String

Fix accidental overwrite of filebased cp file
diff --git a/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/internal/client/model/connectionmanager/xmlrpc/XmlRpcClientManager.java b/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/internal/client/model/connectionmanager/xmlrpc/XmlRpcClientManager.java
index b22d5ed..b83ab36 100644
--- a/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/internal/client/model/connectionmanager/xmlrpc/XmlRpcClientManager.java
+++ b/bundles/org.eclipse.emf.emfstore.client/src/org/eclipse/emf/emfstore/internal/client/model/connectionmanager/xmlrpc/XmlRpcClientManager.java
@@ -269,7 +269,7 @@
 					fragmentIndex
 				});
 				for (final String s : envelope.getFragment()) {
-					writer.write(s + "\n"); //$NON-NLS-1$
+					writer.write(s + System.getProperty("line.separator")); //$NON-NLS-1$
 				}
 				fragmentIndex += 1;
 			} while (!envelope.isLast());
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 6a38064..36136bd 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
@@ -150,7 +150,7 @@
 	/**
 	 * Since an XML Resource needs exactly one root object, we have to write a dummy object to the stream.
 	 *
-	 * @param pos the outputstream
+	 * @param pos the {@link PipedOutputStream}
 	 * @throws IOException in case there is a problem during write
 	 */
 	private static void writeDummyResourceToStream(PipedOutputStream pos) throws IOException {
@@ -224,6 +224,7 @@
 
 		if (currentOpIndex < 0) {
 			try {
+				writeDummyResourceToStream(pos);
 				pos.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/operations/util/ChangePackageUtil.java b/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/operations/util/ChangePackageUtil.java
index 1e4e932..5ea8e7f 100644
--- a/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/operations/util/ChangePackageUtil.java
+++ b/bundles/org.eclipse.emf.emfstore.server.model/src/org/eclipse/emf/emfstore/internal/server/model/versioning/operations/util/ChangePackageUtil.java
@@ -14,12 +14,16 @@
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
+import java.io.IOException;
+import java.io.LineNumberReader;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.LineIterator;
 import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.emfstore.internal.common.model.util.FileUtil;
@@ -81,30 +85,8 @@
 
 			private int fragmentIndex;
 			private int count;
-			private boolean isInitialized;
 			private ChangePackageEnvelope envelope;
-
-			private void init() {
-				int leafSizeCounter = 0;
-				final ESCloseableIterable<AbstractOperation> operations = changePackage.operations();
-				try {
-					for (final AbstractOperation operation : operations.iterable()) {
-						final int countLeafOperations = countLeafOperations(operation);
-						leafSizeCounter += countLeafOperations;
-						if (leafSizeCounter < changePackageFragmentSize) {
-							continue;
-						}
-						leafSizeCounter = 0;
-						count += 1;
-					}
-				} finally {
-					operations.close();
-				}
-				if (leafSizeCounter != 0 || count == 0) {
-					count += 1;
-				}
-				isInitialized = true;
-			}
+			private boolean isInitialized;
 
 			public boolean hasNext() {
 
@@ -117,34 +99,72 @@
 					envelope.setFragmentCount(count);
 				}
 
-				int envelopeSize = 0;
-
-				FileReader reader;
-				try {
-					reader = new FileReader(new File(changePackage.getTempFilePath()));
-					final LineIterator lineIterator = new LineIterator(reader);
-					final StringBuffer b = new StringBuffer();
-
-					while (envelopeSize < changePackageFragmentSize && lineIterator.hasNext()) {
-						final String nextLine = lineIterator.next();
-						envelope.getFragment().add(nextLine);
-						b.append(nextLine + "\n"); //$NON-NLS-1$
-						envelopeSize += 1;
-					}
-					b.toString();
-				} catch (final FileNotFoundException ex) {
-					throw new IllegalStateException(ex);
-				}
+				final List<String> readLines = readLines(fragmentIndex * changePackageFragmentSize, changePackage,
+					changePackageFragmentSize);
+				envelope.getFragment().addAll(readLines);
 
 				envelope.setFragmentIndex(fragmentIndex);
 
-				if (envelope.getFragment().size() == changePackageFragmentSize || fragmentIndex == 0) {
+				if (!envelope.getFragment().isEmpty() || fragmentIndex == 0) {
 					return true;
 				}
 
 				return false;
 			}
 
+			private void init() {
+				LineNumberReader lineNumberReader = null;
+				try {
+					lineNumberReader = new LineNumberReader(new FileReader(new File(changePackage.getTempFilePath())));
+					lineNumberReader.skip(Long.MAX_VALUE);
+					final int lines = lineNumberReader.getLineNumber() + 1;
+					count = lines / changePackageFragmentSize;
+					if (lines % changePackageFragmentSize != 0) {
+						count += 1;
+					}
+				} catch (final FileNotFoundException ex) {
+					throw new IllegalStateException(ex);
+				} catch (final IOException ex) {
+					throw new IllegalStateException(ex);
+				} finally {
+					IOUtils.closeQuietly(lineNumberReader);
+				}
+				isInitialized = true;
+			}
+
+			private List<String> readLines(int from, final FileBasedChangePackage changePackage,
+				final int changePackageFragmentSize) {
+
+				int readLines = 0;
+				FileReader reader;
+				final List<String> lines = new ArrayList<String>();
+
+				try {
+					reader = new FileReader(new File(changePackage.getTempFilePath()));
+					final LineIterator lineIterator = new LineIterator(reader);
+					int read = 0;
+
+					while (read < from) {
+						if (!lineIterator.hasNext()) {
+							return lines;
+						}
+						lineIterator.next();
+						read += 1;
+					}
+
+					while (readLines < changePackageFragmentSize && lineIterator.hasNext()) {
+						final String nextLine = lineIterator.next();
+						readLines += 1;
+						lines.add(nextLine);
+					}
+
+				} catch (final FileNotFoundException ex) {
+					throw new IllegalStateException(ex);
+				}
+
+				return lines;
+			}
+
 			public ChangePackageEnvelope next() {
 				if (envelope == null) {
 					final boolean hasNext = hasNext();
diff --git a/bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/core/subinterfaces/ChangePackageFragmentUploadAdapter.java b/bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/core/subinterfaces/ChangePackageFragmentUploadAdapter.java
index ee810dd..151d731 100644
--- a/bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/core/subinterfaces/ChangePackageFragmentUploadAdapter.java
+++ b/bundles/org.eclipse.emf.emfstore.server/src/org/eclipse/emf/emfstore/internal/server/core/subinterfaces/ChangePackageFragmentUploadAdapter.java
@@ -60,9 +60,9 @@
 		}
 		FileWriter writer = null;
 		try {
-			writer = new FileWriter(file);
+			writer = new FileWriter(file, true);
 			for (final String str : fragment) {
-				writer.write(str + "\n"); //$NON-NLS-1$
+				writer.write(str + System.getProperty("line.separator")); //$NON-NLS-1$
 			}
 		} catch (final IOException ex) {
 			throw new ESException(Messages.ChangePackageFragmentUploadAdapter_SplittingFailed, ex);