/*******************************************************************************
 * Copyright (c) 2009, 2019 Xored Software Inc and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *     Xored Software Inc - initial API and implementation and/or initial documentation
 *******************************************************************************/
package org.eclipse.rcptt.ecl.core.util;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EDataType;
import org.eclipse.emf.ecore.EFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.FeatureMap;
import org.eclipse.emf.ecore.util.FeatureMapUtil;
import org.eclipse.emf.ecore.util.InternalEList;

public class ECLBinaryResourceImpl extends ResourceImpl {
	/**
	 * Specify the capacity of the buffered stream used when
	 * {@link #doSave(OutputStream, Map) saving} or
	 * {@link #doLoad(InputStream, Map) loading} the resource content. The value
	 * must be an integer. If not specified, {@link #DEFAULT_BUFFER_CAPACITY} is
	 * used. A value less than one disables the cache.
	 * 
	 * @since 2.6
	 */
	public static final String OPTION_BUFFER_CAPACITY = "BUFFER_CAPACITY";

	/**
	 * The default {@link #OPTION_BUFFER_CAPACITY} capacity of the buffered
	 * stream used when {@link #doSave(OutputStream, Map) saving} or
	 * {@link #doLoad(InputStream, Map) loading} the resource content.
	 * 
	 * @since 2.6
	 */
	public static final int DEFAULT_BUFFER_CAPACITY = 1024;

	/**
	 * Extract the {@link #OPTION_BUFFER_CAPACITY} from the options.
	 * 
	 * @param options
	 *            a map of options.
	 * @return the value associated with the {@link #OPTION_BUFFER_CAPACITY} key
	 *         in the options map.
	 * @since 2.6
	 */
	protected static int getBufferCapacity(Map<?, ?> options) {
		if (options != null) {
			Integer capacity = (Integer) options.get(OPTION_BUFFER_CAPACITY);
			if (capacity != null) {
				return capacity;
			}
		}
		return DEFAULT_BUFFER_CAPACITY;
	}

	public ECLBinaryResourceImpl() {
		super();
	}

	public ECLBinaryResourceImpl(URI uri) {
		super(uri);
	}

	@Override
	protected void doSave(OutputStream outputStream, Map<?, ?> options)
			throws IOException {
		boolean buffer = !(outputStream instanceof BufferedOutputStream);
		if (buffer) {
			int bufferCapacity = getBufferCapacity(options);
			if (bufferCapacity > 0) {
				outputStream = new BufferedOutputStream(outputStream,
						bufferCapacity);
			} else {
				buffer = false;
			}
		}

		try {
			EObjectOutputStream eObjectOutputStream = new EObjectOutputStream(
					outputStream, options);
			eObjectOutputStream.saveResource(this);
		} finally {
			if (buffer) {
				outputStream.flush();
			}
		}
	}

	@Override
	protected void doLoad(InputStream inputStream, Map<?, ?> options)
			throws IOException {
		if (!(inputStream instanceof BufferedInputStream)) {
			int bufferCapacity = getBufferCapacity(options);
			if (bufferCapacity > 0) {
				inputStream = new BufferedInputStream(inputStream,
						bufferCapacity);
			}
		}

		EObjectInputStream eObjectInputStream = new EObjectInputStream(
				inputStream, options);
		eObjectInputStream.loadResource(this);
	}

	public static class BinaryIO {
		public enum Version {
			VERSION_1_0
		}

		protected Version version;
		protected Resource resource;
		protected URI baseURI;
		protected Map<?, ?> options;
		protected char[] characters;
		protected InternalEObject[][] internalEObjectDataArrayBuffer = new InternalEObject[50][];
		protected int internalEObjectDataArrayBufferCount = -1;

		protected URI resolve(URI uri) {
			return baseURI != null && uri.isRelative() && uri.hasRelativePath() ? uri
					.resolve(baseURI) : uri;
		}

		protected URI deresolve(URI uri) {
			if (baseURI != null && !uri.isRelative()) {
				URI deresolvedURI = uri.deresolve(baseURI, true, true, false);
				if (deresolvedURI.hasRelativePath()
						&& (!uri.isPlatform() || uri.segment(0).equals(
								baseURI.segment(0)))) {
					uri = deresolvedURI;
				}
			}
			return uri;
		}

		protected InternalEObject[] allocateInternalEObjectArray(int length) {
			if (internalEObjectDataArrayBufferCount == -1) {
				return new InternalEObject[length];
			} else {
				InternalEObject[] buffer = internalEObjectDataArrayBuffer[internalEObjectDataArrayBufferCount];
				internalEObjectDataArrayBuffer[internalEObjectDataArrayBufferCount--] = null;
				return buffer.length >= length ? buffer
						: new InternalEObject[length];
			}
		}

		protected void recycle(InternalEObject[] values) {
			if (++internalEObjectDataArrayBufferCount >= internalEObjectDataArrayBuffer.length) {
				InternalEObject[][] newInternalEObjectDataArrayBuffer = new InternalEObject[internalEObjectDataArrayBufferCount * 2][];
				System.arraycopy(internalEObjectDataArrayBuffer, 0,
						newInternalEObjectDataArrayBuffer, 0,
						internalEObjectDataArrayBufferCount);
				internalEObjectDataArrayBuffer = newInternalEObjectDataArrayBuffer;
			}
			internalEObjectDataArrayBuffer[internalEObjectDataArrayBufferCount] = values;
		}

		protected FeatureMap.Entry.Internal[][] featureMapEntryDataArrayBuffer = new FeatureMap.Entry.Internal[50][];
		protected int featureMapEntryDataArrayBufferCount = -1;

		protected FeatureMap.Entry.Internal[] allocateFeatureMapEntryArray(
				int length) {
			if (featureMapEntryDataArrayBufferCount == -1) {
				return new FeatureMap.Entry.Internal[length];
			} else {
				FeatureMap.Entry.Internal[] buffer = featureMapEntryDataArrayBuffer[featureMapEntryDataArrayBufferCount];
				featureMapEntryDataArrayBuffer[featureMapEntryDataArrayBufferCount--] = null;
				return buffer.length >= length ? buffer
						: new FeatureMap.Entry.Internal[length];
			}
		}

		protected void recycle(FeatureMap.Entry.Internal[] values) {
			if (++featureMapEntryDataArrayBufferCount >= featureMapEntryDataArrayBuffer.length) {
				FeatureMap.Entry.Internal[][] newFeatureMapEntryDataArrayBuffer = new FeatureMap.Entry.Internal[featureMapEntryDataArrayBufferCount * 2][];
				System.arraycopy(featureMapEntryDataArrayBuffer, 0,
						newFeatureMapEntryDataArrayBuffer, 0,
						featureMapEntryDataArrayBufferCount);
				featureMapEntryDataArrayBuffer = newFeatureMapEntryDataArrayBuffer;
			}
			featureMapEntryDataArrayBuffer[featureMapEntryDataArrayBufferCount] = values;
		}

		protected enum FeatureKind {
			EOBJECT_CONTAINER, EOBJECT_CONTAINER_PROXY_RESOLVING,

			EOBJECT, EOBJECT_PROXY_RESOLVING,

			EOBJECT_LIST, EOBJECT_LIST_PROXY_RESOLVING,

			EOBJECT_CONTAINMENT, EOBJECT_CONTAINMENT_PROXY_RESOLVING,

			EOBJECT_CONTAINMENT_LIST, EOBJECT_CONTAINMENT_LIST_PROXY_RESOLVING,

			BOOLEAN, BYTE, CHAR, DOUBLE, FLOAT, INT, LONG, SHORT, STRING,

			DATA, DATA_LIST,

			FEATURE_MAP;

			public static FeatureKind get(EStructuralFeature eStructuralFeature) {
				if (eStructuralFeature instanceof EReference) {
					EReference eReference = (EReference) eStructuralFeature;
					if (eReference.isContainment()) {
						if (eReference.isResolveProxies()) {
							if (eReference.isMany()) {
								return EOBJECT_CONTAINMENT_LIST_PROXY_RESOLVING;
							} else {
								return EOBJECT_CONTAINMENT_PROXY_RESOLVING;
							}
						} else {
							if (eReference.isMany()) {
								return EOBJECT_CONTAINMENT_LIST;
							} else {
								return EOBJECT_CONTAINMENT;
							}
						}
					} else if (eReference.isContainer()) {
						if (eReference.isResolveProxies()) {
							return EOBJECT_CONTAINER_PROXY_RESOLVING;
						} else {
							return EOBJECT_CONTAINER;
						}
					} else if (eReference.isResolveProxies()) {
						if (eReference.isMany()) {
							return EOBJECT_LIST_PROXY_RESOLVING;
						} else {
							return EOBJECT_PROXY_RESOLVING;
						}
					} else {
						if (eReference.isMany()) {
							return EOBJECT_LIST;
						} else {
							return EOBJECT;
						}
					}
				} else {
					EAttribute eAttribute = (EAttribute) eStructuralFeature;
					EDataType eDataType = eAttribute.getEAttributeType();
					String instanceClassName = eDataType.getInstanceClassName();
					if (instanceClassName == "org.eclipse.emf.ecore.util.FeatureMap$Entry") {
						return FEATURE_MAP;
					} else if (eAttribute.isMany()) {
						return DATA_LIST;
					} else if (instanceClassName == "java.lang.String") {
						return STRING;
					} else if (instanceClassName == "boolean") {
						return BOOLEAN;
					} else if (instanceClassName == "byte") {
						return BYTE;
					} else if (instanceClassName == "char") {
						return CHAR;
					} else if (instanceClassName == "double") {
						return DOUBLE;
					} else if (instanceClassName == "float") {
						return FLOAT;
					} else if (instanceClassName == "int") {
						return INT;
					} else if (instanceClassName == "long") {
						return LONG;
					} else if (instanceClassName == "short") {
						return SHORT;
					} else {
						return DATA;
					}
				}
			}
		}
	}

	public static class EObjectOutputStream extends BinaryIO {
		public enum Check {
			NOTHING, DIRECT_RESOURCE, RESOURCE, CONTAINER
		}

		protected static class EPackageData {
			public int id;
			public EClassData[] eClassData;

			public final int allocateEClassID() {
				for (int i = 0, length = eClassData.length; i < length; ++i) {
					EClassData eClassData = this.eClassData[i];
					if (eClassData == null) {
						return i;
					}
				}
				return -1;
			}
		}

		protected static class EClassData {
			public int ePackageID;
			public int id;
			public EStructuralFeatureData[] eStructuralFeatureData;
		}

		protected static class EStructuralFeatureData {
			public String name;
			public boolean isTransient;
			public FeatureKind kind;
			public EFactory eFactory;
			public EDataType eDataType;
		}

		protected OutputStream outputStream;
		protected Map<EPackage, EPackageData> ePackageDataMap = new HashMap<EPackage, EPackageData>();
		protected Map<EClass, EClassData> eClassDataMap = new HashMap<EClass, EClassData>();
		protected Map<EObject, Integer> eObjectIDMap = new HashMap<EObject, Integer>();
		protected Map<URI, Integer> uriToIDMap = new HashMap<URI, Integer>();

		public EObjectOutputStream(OutputStream outputStream, Map<?, ?> options)
				throws IOException {
			this(outputStream, options, Version.VERSION_1_0);
		}

		public EObjectOutputStream(OutputStream outputStream,
				Map<?, ?> options, Version version) throws IOException {
			this.outputStream = outputStream;
			this.options = options;
			this.version = version;
			writeSignature();
			writeVersion();
		}

		protected void writeSignature() throws IOException {
			// Write a signature that will be obviously corrupt
			// if the binary contents end up being UTF-8 encoded
			// or altered by line feed or carriage return changes.
			//
			writeByte('\211');
			writeByte('e');
			writeByte('m');
			writeByte('f');
			writeByte('\n');
			writeByte('\r');
			writeByte('\032');
			writeByte('\n');
		}

		protected void writeVersion() throws IOException {
			writeByte(version.ordinal());
		}

		protected EPackageData writeEPackage(EPackage ePackage)
				throws IOException {
			EPackageData ePackageData = ePackageDataMap.get(ePackage);
			if (ePackageData == null) {
				ePackageData = new EPackageData();
				int id = ePackageDataMap.size();
				ePackageData.id = id;
				ePackageData.eClassData = new EClassData[ePackage
						.getEClassifiers().size()];
				writeCompressedInt(id);
				writeString(ePackage.getNsURI());
				writeURI(EcoreUtil.getURI(ePackage));
				ePackageDataMap.put(ePackage, ePackageData);
			} else {
				writeCompressedInt(ePackageData.id);
			}
			return ePackageData;
		}

		protected EClassData writeEClass(EClass eClass) throws IOException {
			EClassData eClassData = eClassDataMap.get(eClass);
			if (eClassData == null) {
				eClassData = new EClassData();
				EPackageData ePackageData = writeEPackage(eClass.getEPackage());
				eClassData.ePackageID = ePackageData.id;
				writeCompressedInt(eClassData.id = ePackageData
						.allocateEClassID());
				writeString(eClass.getName());
				int featureCount = eClass.getFeatureCount();
				EStructuralFeatureData[] eStructuralFeaturesData = eClassData.eStructuralFeatureData = new EStructuralFeatureData[featureCount];
				for (int i = 0; i < featureCount; ++i) {
					EStructuralFeatureData eStructuralFeatureData = eStructuralFeaturesData[i] = new EStructuralFeatureData();
					EStructuralFeature.Internal eStructuralFeature = (EStructuralFeature.Internal) eClass
							.getEStructuralFeature(i);
					eStructuralFeatureData.name = eStructuralFeature.getName();
					eStructuralFeatureData.isTransient = eStructuralFeature
							.isTransient()
							|| eStructuralFeature.isContainer()
							&& !eStructuralFeature.isResolveProxies();
					eStructuralFeatureData.kind = FeatureKind
							.get(eStructuralFeature);
					if (eStructuralFeature instanceof EAttribute) {
						EAttribute eAttribute = (EAttribute) eStructuralFeature;
						EDataType eDataType = eAttribute.getEAttributeType();
						eStructuralFeatureData.eDataType = eDataType;
						eStructuralFeatureData.eFactory = eDataType
								.getEPackage().getEFactoryInstance();
					}
				}
				ePackageData.eClassData[eClassData.id] = eClassData;
				eClassDataMap.put(eClass, eClassData);
			} else {
				writeCompressedInt(eClassData.ePackageID);
				writeCompressedInt(eClassData.id);
			}
			return eClassData;
		}

		protected EStructuralFeatureData writeEStructuralFeature(
				EStructuralFeature eStructuralFeature) throws IOException {
			EClass eClass = eStructuralFeature.getEContainingClass();
			EClassData eClassData = writeEClass(eClass);
			int featureID = eClass.getFeatureID(eStructuralFeature);
			EStructuralFeatureData eStructuralFeatureData = eClassData.eStructuralFeatureData[featureID];
			writeCompressedInt(featureID);
			if (eStructuralFeatureData.name != null) {
				writeString(eStructuralFeatureData.name);
				eStructuralFeatureData.name = null;
			}
			return eStructuralFeatureData;
		}

		public void saveResource(Resource resource) throws IOException {
			this.resource = resource;
			URI uri = resource.getURI();
			if (uri != null && uri.isHierarchical() && !uri.isRelative()) {
				baseURI = uri;
			}
			@SuppressWarnings("unchecked")
			InternalEList<? extends InternalEObject> internalEList = (InternalEList<? extends InternalEObject>) (InternalEList<?>) resource
					.getContents();
			saveEObjects(internalEList, Check.CONTAINER);
		}

		public void saveEObjects(
				InternalEList<? extends InternalEObject> internalEObjects,
				Check check) throws IOException {
			int size = internalEObjects.size();
			InternalEObject[] values = allocateInternalEObjectArray(size);
			internalEObjects.basicToArray(values);
			writeCompressedInt(size);
			for (int i = 0; i < size; ++i) {
				InternalEObject internalEObject = values[i];
				saveEObject(internalEObject, check);
			}
			recycle(values);
		}

		public void saveFeatureMap(FeatureMap.Internal featureMap)
				throws IOException {
			int size = featureMap.size();
			FeatureMap.Entry.Internal[] values = allocateFeatureMapEntryArray(size);
			featureMap.toArray(values);
			writeCompressedInt(size);
			for (int i = 0; i < size; ++i) {
				FeatureMap.Entry.Internal entry = values[i];
				saveFeatureMapEntry(entry);
			}
			recycle(values);
		}

		public void saveFeatureMapEntry(FeatureMap.Entry.Internal entry)
				throws IOException {
			EStructuralFeatureData eStructuralFeatureData = writeEStructuralFeature(entry
					.getEStructuralFeature());
			Object value = entry.getValue();
			switch (eStructuralFeatureData.kind) {
			case EOBJECT:
			case EOBJECT_LIST:
			case EOBJECT_CONTAINMENT:
			case EOBJECT_CONTAINMENT_LIST: {
				saveEObject((InternalEObject) value, Check.NOTHING);
				break;
			}
			case EOBJECT_CONTAINMENT_PROXY_RESOLVING:
			case EOBJECT_CONTAINMENT_LIST_PROXY_RESOLVING: {
				saveEObject((InternalEObject) value, Check.DIRECT_RESOURCE);
				break;
			}
			case EOBJECT_PROXY_RESOLVING:
			case EOBJECT_LIST_PROXY_RESOLVING: {
				saveEObject((InternalEObject) value, Check.RESOURCE);
				break;
			}
			case BOOLEAN: {
				writeBoolean((Boolean) value);
				break;
			}
			case BYTE: {
				writeByte((Byte) value);
				break;
			}
			case CHAR: {
				writeChar((Character) value);
				break;
			}
			case DOUBLE: {
				writeDouble((Double) value);
				break;
			}
			case FLOAT: {
				writeFloat((Float) value);
				break;
			}
			case INT: {
				writeInt((Integer) value);
				break;
			}
			case LONG: {
				writeLong((Long) value);
				break;
			}
			case SHORT: {
				writeShort((Short) value);
				break;
			}
			case STRING: {
				writeString((String) value);
				break;
			}
			case DATA:
			case DATA_LIST: {
				String literal = eStructuralFeatureData.eFactory
						.convertToString(eStructuralFeatureData.eDataType,
								value);
				writeString(literal);
				break;
			}
			default: {
				throw new IOException("Unhandled case "
						+ eStructuralFeatureData.kind);
			}
			}
		}

		public void saveEObject(InternalEObject internalEObject, Check check)
				throws IOException {
			if (internalEObject == null) {
				writeCompressedInt(-1);
			} else {
				Integer id = eObjectIDMap.get(internalEObject);
				if (id == null) {
					int idValue = eObjectIDMap.size();
					writeCompressedInt(idValue);
					eObjectIDMap.put(internalEObject, idValue);
					EClass eClass = internalEObject.eClass();
					EClassData eClassData = writeEClass(eClass);
					switch (check) {
					case DIRECT_RESOURCE: {
						Internal resource = internalEObject.eDirectResource();
						if (resource != null) {
							writeCompressedInt(-1);
							writeURI(resource.getURI(),
									resource.getURIFragment(internalEObject));
							return;
						} else if (internalEObject.eIsProxy()) {
							writeCompressedInt(-1);
							writeURI(internalEObject.eProxyURI());
							return;
						}
						break;
					}
					case RESOURCE: {
						Resource resource = internalEObject.eResource();
						if (resource != this.resource && resource != null) {
							writeCompressedInt(-1);
							writeURI(resource.getURI(),
									resource.getURIFragment(internalEObject));
							return;
						} else if (internalEObject.eIsProxy()) {
							writeCompressedInt(-1);
							writeURI(internalEObject.eProxyURI());
							return;
						}
						break;
					}
					case NOTHING:
					case CONTAINER: {
						break;
					}
					}
					EStructuralFeatureData[] eStructuralFeatureData = eClassData.eStructuralFeatureData;
					for (int i = 0, length = eStructuralFeatureData.length; i < length; ++i) {
						EStructuralFeatureData structuralFeatureData = eStructuralFeatureData[i];
						if (!structuralFeatureData.isTransient
								&& (structuralFeatureData.kind != FeatureKind.EOBJECT_CONTAINER_PROXY_RESOLVING || check == Check.CONTAINER)) {
							saveFeatureValue(internalEObject, i,
									structuralFeatureData);
						}
					}
					writeCompressedInt(0);
				} else {
					writeCompressedInt(id);
				}
			}
		}

		protected void saveFeatureValue(InternalEObject internalEObject,
				int featureID, EStructuralFeatureData eStructuralFeatureData)
				throws IOException {
			if (internalEObject.eIsSet(featureID)) {
				writeCompressedInt(featureID + 1);
				if (eStructuralFeatureData.name != null) {
					writeString(eStructuralFeatureData.name);
					eStructuralFeatureData.name = null;
				}
				Object value = internalEObject.eGet(featureID, false, true);
				switch (eStructuralFeatureData.kind) {
				case EOBJECT:
				case EOBJECT_CONTAINMENT: {
					saveEObject((InternalEObject) value, Check.NOTHING);
					break;
				}
				case EOBJECT_CONTAINER_PROXY_RESOLVING: {
					saveEObject((InternalEObject) value, Check.DIRECT_RESOURCE);
					break;
				}
				case EOBJECT_CONTAINMENT_PROXY_RESOLVING: {
					saveEObject((InternalEObject) value, Check.DIRECT_RESOURCE);
					break;
				}
				case EOBJECT_PROXY_RESOLVING: {
					saveEObject((InternalEObject) value, Check.RESOURCE);
					break;
				}
				case EOBJECT_LIST:
				case EOBJECT_CONTAINMENT_LIST: {
					@SuppressWarnings("unchecked")
					InternalEList<? extends InternalEObject> internalEList = (InternalEList<? extends InternalEObject>) value;
					saveEObjects(internalEList, Check.NOTHING);
					break;
				}
				case EOBJECT_CONTAINMENT_LIST_PROXY_RESOLVING: {
					@SuppressWarnings("unchecked")
					InternalEList<? extends InternalEObject> internalEList = (InternalEList<? extends InternalEObject>) value;
					saveEObjects(internalEList, Check.DIRECT_RESOURCE);
					break;
				}
				case EOBJECT_LIST_PROXY_RESOLVING: {
					@SuppressWarnings("unchecked")
					InternalEList<? extends InternalEObject> internalEList = (InternalEList<? extends InternalEObject>) value;
					saveEObjects(internalEList, Check.RESOURCE);
					break;
				}
				case BOOLEAN: {
					writeBoolean((Boolean) value);
					break;
				}
				case BYTE: {
					writeByte((Byte) value);
					break;
				}
				case CHAR: {
					writeChar((Character) value);
					break;
				}
				case DOUBLE: {
					writeDouble((Double) value);
					break;
				}
				case FLOAT: {
					writeFloat((Float) value);
					break;
				}
				case INT: {
					writeInt((Integer) value);
					break;
				}
				case LONG: {
					writeLong((Long) value);
					break;
				}
				case SHORT: {
					writeShort((Short) value);
					break;
				}
				case STRING: {
					writeString((String) value);
					break;
				}
				case FEATURE_MAP: {
					FeatureMap.Internal featureMap = (FeatureMap.Internal) value;
					saveFeatureMap(featureMap);
					break;
				}
				case DATA: {
					String literal = eStructuralFeatureData.eFactory
							.convertToString(eStructuralFeatureData.eDataType,
									value);
					writeString(literal);
					break;
				}
				case DATA_LIST: {
					List<?> dataValues = (List<?>) value;
					int length = dataValues.size();
					writeCompressedInt(length);
					for (int j = 0; j < length; ++j) {
						String literal = eStructuralFeatureData.eFactory
								.convertToString(
										eStructuralFeatureData.eDataType,
										dataValues.get(j));
						writeString(literal);
					}
					break;
				}
				default: {
					throw new IOException("Unhandled case "
							+ eStructuralFeatureData.kind);
				}
				}
			}
		}

		public void writeByte(int value) throws IOException {
			outputStream.write(value);
		}

		public void writeBoolean(boolean value) throws IOException {
			writeByte(value ? 1 : 0);
		}

		public void writeChar(int value) throws IOException {
			writeByte((byte) (value >> 8 & 0xFF));
			writeByte((byte) (value & 0xFF));
		}

		public void writeShort(int value) throws IOException {
			writeByte((byte) (value >> 8 & 0xFF));
			writeByte((byte) (value & 0xFF));
		}

		public void writeInt(int value) throws IOException {
			writeByte((byte) (value >> 24 & 0xFF));
			writeByte((byte) (value >> 16 & 0xFF));
			writeByte((byte) (value >> 8 & 0xFF));
			writeByte((byte) (value & 0xFF));
		}

		public void writeLong(long value) throws IOException {
			writeInt((int) (value >> 32));
			writeInt((int) value);
		}

		public void writeFloat(float value) throws IOException {
			writeInt(Float.floatToIntBits(value));
		}

		public void writeDouble(double value) throws IOException {
			writeLong(Double.doubleToLongBits(value));
		}

		public void writeCompressedInt(int value) throws IOException {
			++value;
			int firstByte = value >> 24 & 0xFF;
			int secondByte = value >> 16 & 0xFF;
			int thirdByte = value >> 8 & 0xFF;
			int fourthBtye = value & 0xFF;
			if (firstByte > 0x3F) {
				handleInvalidValue(value);
			} else if (firstByte != 0 || secondByte > 0x3F) {
				writeByte(firstByte | 0xC0);
				writeByte(secondByte);
				writeByte(thirdByte);
				writeByte(fourthBtye);
			} else if (secondByte != 0 || thirdByte > 0x3F) {
				writeByte(secondByte | 0x80);
				writeByte(thirdByte);
				writeByte(fourthBtye);
			} else if (thirdByte != 0 || fourthBtye > 0x3F) {
				writeByte(thirdByte | 0x40);
				writeByte(fourthBtye);
			} else {
				writeByte(fourthBtye);
			}
		}

		private final void handleInvalidValue(int value) throws IOException {
			throw new IOException("Invalid value " + value);
		}

		public void writeString(String value) throws IOException {
			if (value == null) {
				writeCompressedInt(-1);
			} else {
				int length = value.length();
				writeCompressedInt(length);
				if (characters == null || characters.length < length) {
					characters = new char[length];
				}
				value.getChars(0, length, characters, 0);
				LOOP: for (int i = 0; i < length; ++i) {
					char character = characters[i];
					if (character == 0 || character > 0xFF) {
						writeByte((byte) 0);
						writeChar(character);
						while (++i < length) {
							writeChar(characters[i]);
						}
						break LOOP;
					} else {
						writeByte((byte) character);
					}
				}
			}
		}

		public void writeURI(URI uri) throws IOException {
			writeURI(uri.trimFragment(), uri.fragment());
		}

		public void writeURI(URI uri, String fragment) throws IOException {
			if (uri == null) {
				writeCompressedInt(-1);
			} else {
				assert uri.fragment() == null;
				Integer id = uriToIDMap.get(uri);
				if (id == null) {
					int idValue = uriToIDMap.size();
					uriToIDMap.put(uri, idValue);
					writeCompressedInt(idValue);
					writeString(deresolve(uri).toString());
				} else {
					writeCompressedInt(id);
				}
				writeString(fragment);
			}
		}
	}

	public static class EObjectInputStream extends BinaryIO {
		protected static class EPackageData {
			public EPackage ePackage;
			public EClassData[] eClassData;

			public final int allocateEClassID() {
				for (int i = 0, length = eClassData.length; i < length; ++i) {
					EClassData eClassData = this.eClassData[i];
					if (eClassData == null) {
						return i;
					}
				}
				return -1;
			}
		}

		protected static class EClassData {
			public EClass eClass;
			public EFactory eFactory;
			public EStructuralFeatureData[] eStructuralFeatureData;

		}

		protected static class EStructuralFeatureData {
			public int featureID;
			public EStructuralFeature eStructuralFeature;
			public FeatureKind kind;
			public EFactory eFactory;
			public EDataType eDataType;
		}

		protected ResourceSet resourceSet;
		protected InputStream inputStream;
		protected List<EPackageData> ePackageDataList = new ArrayList<EPackageData>();
		protected List<EClassData> eClassDataList = new ArrayList<EClassData>();
		protected List<InternalEObject> eObjectList = new ArrayList<InternalEObject>();
		protected List<URI> uriList = new ArrayList<URI>();

		protected BasicEList<InternalEObject> internalEObjectList = new BasicEList<InternalEObject>();
		protected BasicEList<Object> dataValueList = new BasicEList<Object>();

		public EObjectInputStream(InputStream inputStream, Map<?, ?> options)
				throws IOException {
			this.inputStream = inputStream;
			this.options = options;
			readSignature();
			readVersion();
		}

		protected void readSignature() throws IOException {
			if (readByte() != (byte) '\211' || readByte() != 'e'
					|| readByte() != 'm' || readByte() != 'f'
					|| readByte() != '\n' || readByte() != '\r'
					|| readByte() != '\032' || readByte() != '\n') {
				throw new IOException(
						"Invalid signature for a binary EMF serialization");
			}
		}

		protected void readVersion() throws IOException {
			version = Version.values()[readByte()];
		}

		protected int[][] intDataArrayBuffer = new int[50][];
		protected int intDataArrayBufferCount = -1;

		protected int[] allocateIntArray(int length) {
			if (intDataArrayBufferCount == -1) {
				return new int[length];
			} else {
				int[] buffer = intDataArrayBuffer[intDataArrayBufferCount];
				intDataArrayBuffer[intDataArrayBufferCount--] = null;
				return buffer.length >= length ? buffer : new int[length];
			}
		}

		protected void recycle(int[] values) {
			if (++intDataArrayBufferCount >= intDataArrayBuffer.length) {
				int[][] newIntDataArrayBuffer = new int[intDataArrayBufferCount * 2][];
				System.arraycopy(intDataArrayBuffer, 0, newIntDataArrayBuffer,
						0, intDataArrayBufferCount);
				intDataArrayBuffer = newIntDataArrayBuffer;
			}
			intDataArrayBuffer[intDataArrayBufferCount] = values;
		}

		protected EPackageData readEPackage() throws IOException {
			int id = readCompressedInt();
			if (ePackageDataList.size() < id || id < 0) {
				throw new RuntimeException("Package id is not incremented by 1");
			} else if (ePackageDataList.size() == id) {
				EPackageData ePackageData = new EPackageData();
				String nsURI = readString();
				URI uri = readURI();
				if (resourceSet != null) {
					ePackageData.ePackage = EPackage.Registry.INSTANCE
							.getEPackage(nsURI);
					if (ePackageData.ePackage == null) {
						ePackageData.ePackage = (EPackage) resourceSet
								.getEObject(uri, true);
					}
				} else {
					ePackageData.ePackage = EPackage.Registry.INSTANCE
							.getEPackage(nsURI);
				}
				if (ePackageData.ePackage == null)
					throw new NullPointerException("Can load package " + nsURI
							+ ", " + uri.toString());
				ePackageData.eClassData = new EClassData[ePackageData.ePackage
						.getEClassifiers().size()];
				ePackageDataList.add(ePackageData);
				return ePackageData;
			} else {
				return ePackageDataList.get(id);
			}
		}

		protected EClassData readEClass() throws IOException {
			EPackageData ePackageData = readEPackage();
			int id = readCompressedInt();
			EClassData eClassData = ePackageData.eClassData[id];
			if (eClassData == null) {
				eClassData = ePackageData.eClassData[id] = new EClassData();
				String name = readString();
				eClassData.eClass = (EClass) ePackageData.ePackage
						.getEClassifier(name);
				eClassData.eFactory = ePackageData.ePackage
						.getEFactoryInstance();
				eClassData.eStructuralFeatureData = new EStructuralFeatureData[eClassData.eClass
						.getFeatureCount()];
			}
			return eClassData;
		}

		protected EStructuralFeatureData readEStructuralFeature()
				throws IOException {
			EClassData eClassData = readEClass();
			int featureID = readCompressedInt();
			return getEStructuralFeatureData(eClassData, featureID);
		}

		protected EStructuralFeatureData getEStructuralFeatureData(
				EClassData eClassData, int featureID) throws IOException {
			EStructuralFeatureData eStructuralFeatureData = eClassData.eStructuralFeatureData[featureID];
			if (eStructuralFeatureData == null) {
				eStructuralFeatureData = eClassData.eStructuralFeatureData[featureID] = new EStructuralFeatureData();
				String name = readString();
				eStructuralFeatureData.eStructuralFeature = eClassData.eClass
						.getEStructuralFeature(name);
				eStructuralFeatureData.featureID = eClassData.eClass
						.getFeatureID(eStructuralFeatureData.eStructuralFeature);
				eStructuralFeatureData.kind = FeatureKind
						.get(eStructuralFeatureData.eStructuralFeature);
				if (eStructuralFeatureData.eStructuralFeature instanceof EAttribute) {
					EAttribute eAttribute = (EAttribute) eStructuralFeatureData.eStructuralFeature;
					eStructuralFeatureData.eDataType = eAttribute
							.getEAttributeType();
					eStructuralFeatureData.eFactory = eStructuralFeatureData.eDataType
							.getEPackage().getEFactoryInstance();
				}
			}
			return eStructuralFeatureData;
		}

		public void loadResource(Resource resource) throws IOException {
			this.resource = resource;
			this.resourceSet = resource.getResourceSet();
			URI uri = resource.getURI();
			if (uri != null && uri.isHierarchical() && !uri.isRelative()) {
				baseURI = uri;
			}
			int size = readCompressedInt();
			InternalEObject[] values = allocateInternalEObjectArray(size);
			for (int i = 0; i < size; ++i) {
				values[i] = loadEObject();
			}
			internalEObjectList.setData(size, values);
			@SuppressWarnings("unchecked")
			InternalEList<InternalEObject> internalEObjects = (InternalEList<InternalEObject>) (InternalEList<?>) resource
					.getContents();
			internalEObjects.addAllUnique(internalEObjectList);
			recycle(values);
		}

		public void loadEObjects(InternalEList<InternalEObject> internalEObjects)
				throws IOException {
			// Read all the values into an array.
			//
			int size = readCompressedInt();
			InternalEObject[] values = allocateInternalEObjectArray(size);
			for (int i = 0; i < size; ++i) {
				values[i] = loadEObject();
			}
			int existingSize = internalEObjects.size();

			// If the list is empty, we need to add all the objects,
			// otherwise, the reference is bidirectional and the list is at
			// least partially populated.
			//
			if (existingSize == 0) {
				internalEObjectList.setData(size, values);
				internalEObjects.addAllUnique(internalEObjectList);
			} else {
				InternalEObject[] existingValues = allocateInternalEObjectArray(existingSize);
				internalEObjects.basicToArray(existingValues);
				int[] indices = allocateIntArray(existingSize);
				int duplicateCount = 0;
				LOOP: for (int i = 0; i < size; ++i) {
					InternalEObject internalEObject = values[i];
					for (int j = 0, count = 0; j < existingSize; ++j) {
						InternalEObject existingInternalEObject = existingValues[j];
						if (existingInternalEObject == internalEObject) {
							if (duplicateCount != count) {
								internalEObjects.move(duplicateCount, count);
							}
							indices[duplicateCount] = i;
							++count;
							++duplicateCount;
							existingValues[j] = null;
							continue LOOP;
						} else if (existingInternalEObject != null) {
							++count;
						}
					}

					values[i - duplicateCount] = internalEObject;
				}

				size -= existingSize;
				internalEObjectList.setData(size, values);
				internalEObjects.addAllUnique(0, internalEObjectList);
				for (int i = 0; i < existingSize; ++i) {
					int newPosition = indices[i];
					int oldPosition = size + i;
					if (newPosition != oldPosition) {
						internalEObjects.move(newPosition, oldPosition);
					}
				}
				recycle(existingValues);
				recycle(indices);
			}
			recycle(values);
		}

		public void loadFeatureMap(FeatureMap.Internal featureMap)
				throws IOException {
			// Read all the values into an array.
			//
			int size = readCompressedInt();
			FeatureMap.Entry.Internal[] values = allocateFeatureMapEntryArray(size);
			for (int i = 0; i < size; ++i) {
				values[i] = loadFeatureMapEntry();
			}
			int existingSize = featureMap.size();

			// If the list is empty, we need to add all the objects,
			// otherwise, the reference is bidirectional and the list is at
			// least partially populated.
			//
			if (existingSize == 0) {
				featureMap.addAllUnique(values, 0, size);
			} else {
				FeatureMap.Entry.Internal[] existingValues = allocateFeatureMapEntryArray(existingSize);
				featureMap.basicToArray(existingValues);
				int[] indices = allocateIntArray(existingSize);
				int duplicateCount = 0;
				LOOP: for (int i = 0; i < size; ++i) {
					FeatureMap.Entry.Internal entry = values[i];
					for (int j = 0, count = 0; j < existingSize; ++j) {
						FeatureMap.Entry.Internal existingEntry = existingValues[j];
						if (entry.equals(existingEntry)) {
							if (duplicateCount != count) {
								featureMap.move(duplicateCount, count);
							}
							indices[duplicateCount] = i;
							++count;
							++duplicateCount;
							existingValues[j] = null;
							continue LOOP;
						} else if (existingEntry != null) {
							++count;
						}
					}

					values[i - duplicateCount] = entry;
				}

				size -= existingSize;
				internalEObjectList.setData(size, values);
				featureMap.addAllUnique(0, values, 0, size);
				for (int i = 0; i < existingSize; ++i) {
					int newPosition = indices[i];
					int oldPosition = size + i;
					if (newPosition != oldPosition) {
						featureMap.move(newPosition, oldPosition);
					}
				}
				recycle(existingValues);
				recycle(indices);
			}
			recycle(values);
		}

		public FeatureMap.Entry.Internal loadFeatureMapEntry()
				throws IOException {
			EStructuralFeatureData eStructuralFeatureData = readEStructuralFeature();
			Object value;
			switch (eStructuralFeatureData.kind) {
			case EOBJECT_CONTAINER:
			case EOBJECT_CONTAINER_PROXY_RESOLVING:
			case EOBJECT:
			case EOBJECT_LIST:
			case EOBJECT_PROXY_RESOLVING:
			case EOBJECT_LIST_PROXY_RESOLVING:
			case EOBJECT_CONTAINMENT:
			case EOBJECT_CONTAINMENT_LIST:
			case EOBJECT_CONTAINMENT_PROXY_RESOLVING:
			case EOBJECT_CONTAINMENT_LIST_PROXY_RESOLVING: {
				value = loadEObject();
				break;
			}
			case STRING: {
				value = readString();
				break;
			}
			case DATA: {
				String literal = readString();
				value = eStructuralFeatureData.eFactory.createFromString(
						eStructuralFeatureData.eDataType, literal);
				break;
			}
			case BOOLEAN: {
				value = readBoolean();
				break;
			}
			case BYTE: {
				value = readByte();
				break;
			}
			case CHAR: {
				value = readChar();
				break;
			}
			case DOUBLE: {
				value = readDouble();
				break;
			}
			case FLOAT: {
				value = readFloat();
				break;
			}
			case INT: {
				value = readInt();
				break;
			}
			case LONG: {
				value = readLong();
				break;
			}
			case SHORT: {
				value = readShort();
				break;
			}
			default: {
				throw new IOException("Unhandled case "
						+ eStructuralFeatureData.kind);
			}
			}
			return FeatureMapUtil.createRawEntry(
					eStructuralFeatureData.eStructuralFeature, value);
		}

		public InternalEObject loadEObject() throws IOException {
			int id = readCompressedInt();
			if (id == -1) {
				return null;
			} else {
				if (eObjectList.size() <= id) {
					EClassData eClassData = readEClass();
					InternalEObject internalEObject = (InternalEObject) eClassData.eFactory
							.create(eClassData.eClass);
					eObjectList.add(internalEObject);
					for (;;) {
						int featureID = readCompressedInt() - 1;
						if (featureID == -1) {
							break;
						} else if (featureID == -2) {
							internalEObject.eSetProxyURI(readURI());
							break;
						} else {
							EStructuralFeatureData eStructuralFeatureData = getEStructuralFeatureData(
									eClassData, featureID);
							loadFeatureValue(internalEObject,
									eStructuralFeatureData);
						}
					}
					return internalEObject;
				} else {
					return eObjectList.get(id);
				}
			}
		}

		protected void loadFeatureValue(InternalEObject internalEObject,
				EStructuralFeatureData eStructuralFeatureData)
				throws IOException {
			switch (eStructuralFeatureData.kind) {
			case EOBJECT_CONTAINER:
			case EOBJECT_CONTAINER_PROXY_RESOLVING:
			case EOBJECT:
			case EOBJECT_PROXY_RESOLVING:
			case EOBJECT_CONTAINMENT:
			case EOBJECT_CONTAINMENT_PROXY_RESOLVING: {
				internalEObject.eSet(eStructuralFeatureData.featureID,
						loadEObject());
				break;
			}
			case EOBJECT_LIST:
			case EOBJECT_LIST_PROXY_RESOLVING:
			case EOBJECT_CONTAINMENT_LIST:
			case EOBJECT_CONTAINMENT_LIST_PROXY_RESOLVING: {
				@SuppressWarnings("unchecked")
				InternalEList<InternalEObject> internalEList = (InternalEList<InternalEObject>) internalEObject
						.eGet(eStructuralFeatureData.featureID, false, true);
				loadEObjects(internalEList);
				break;
			}
			case STRING: {
				internalEObject.eSet(eStructuralFeatureData.featureID,
						readString());
				break;
			}
			case FEATURE_MAP: {
				FeatureMap.Internal featureMap = (FeatureMap.Internal) internalEObject
						.eGet(eStructuralFeatureData.featureID, false, true);
				loadFeatureMap(featureMap);
				break;
			}
			case DATA: {
				String literal = readString();
				internalEObject.eSet(eStructuralFeatureData.featureID,
						eStructuralFeatureData.eFactory.createFromString(
								eStructuralFeatureData.eDataType, literal));
				break;
			}
			case DATA_LIST: {
				int size = readCompressedInt();
				dataValueList.grow(size);
				Object[] dataValues = dataValueList.data();
				for (int i = 0; i < size; ++i) {
					String literal = readString();
					dataValues[i] = eStructuralFeatureData.eFactory
							.createFromString(eStructuralFeatureData.eDataType,
									literal);
				}
				dataValueList.setData(size, dataValues);
				@SuppressWarnings("unchecked")
				List<Object> values = (List<Object>) internalEObject.eGet(
						eStructuralFeatureData.featureID, false, true);
				values.addAll(dataValueList);
				break;
			}
			case BOOLEAN: {
				internalEObject.eSet(eStructuralFeatureData.featureID,
						readBoolean());
				break;
			}
			case BYTE: {
				internalEObject.eSet(eStructuralFeatureData.featureID,
						readByte());
				break;
			}
			case CHAR: {
				internalEObject.eSet(eStructuralFeatureData.featureID,
						readChar());
				break;
			}
			case DOUBLE: {
				internalEObject.eSet(eStructuralFeatureData.featureID,
						readDouble());
				break;
			}
			case FLOAT: {
				internalEObject.eSet(eStructuralFeatureData.featureID,
						readFloat());
				break;
			}
			case INT: {
				internalEObject.eSet(eStructuralFeatureData.featureID,
						readInt());
				break;
			}
			case LONG: {
				internalEObject.eSet(eStructuralFeatureData.featureID,
						readLong());
				break;
			}
			case SHORT: {
				internalEObject.eSet(eStructuralFeatureData.featureID,
						readShort());
				break;
			}
			default: {
				throw new IOException("Unhandled case "
						+ eStructuralFeatureData.kind);
			}
			}
		}

		public byte readByte() throws IOException {
			int result = inputStream.read();
			if (result == -1) {
				throw new IOException("Unexpected end of stream");
			}
			return (byte) result;
		}

		public boolean readBoolean() throws IOException {
			return readByte() != 0;
		}

		public char readChar() throws IOException {
			return (char) ((readByte() << 8) & 0xFF00 | readByte() & 0xFF);
		}

		public short readShort() throws IOException {
			return (short) ((readByte() << 8) & 0xFF00 | readByte() & 0xFF);
		}

		public int readInt() throws IOException {
			return (readByte() << 24) | (readByte() << 16) & 0xFF0000
					| (readByte() << 8) & 0xFF00 | readByte() & 0xFF;
		}

		public long readLong() throws IOException {
			return (long) readInt() << 32 | readInt() & 0xFFFFFFFFL;
		}

		public float readFloat() throws IOException {
			return Float.intBitsToFloat(readInt());
		}

		public double readDouble() throws IOException {
			return Double.longBitsToDouble(readLong());
		}

		public int readCompressedInt() throws IOException {
			byte initialByte = readByte();
			int code = (initialByte >> 6) & 0x3;
			switch (code) {
			case 0: {
				return initialByte - 1;
			}
			case 1: {
				return (initialByte << 8 & 0x3F00 | readByte() & 0xFF) - 1;
			}
			case 2: {
				return ((initialByte << 16) & 0x3F0000 | (readByte() << 8)
						& 0xFF00 | readByte() & 0xFF) - 1;
			}
			default: {
				return ((initialByte << 24) & 0x3F000000 | (readByte() << 16)
						& 0xFF0000 | (readByte() << 8) & 0xFF00 | readByte() & 0xFF) - 1;
			}
			}
		}

		public String readString() throws IOException {
			int length = readCompressedInt();
			if (length == -1) {
				return null;
			} else {
				if (characters == null || characters.length < length) {
					characters = new char[length];
				}
				LOOP: for (int i = 0; i < length; ++i) {
					byte value = readByte();
					if (value == 0) {
						do {
							characters[i] = readChar();
						} while (++i < length);
						break LOOP;
					} else {
						characters[i] = (char) (value & 0xFF);
					}
				}
				return new String(characters, 0, length);
			}
		}

		public URI readURI() throws IOException {
			int id = readCompressedInt();
			if (id == -1) {
				return null;
			} else {
				URI uri;
				if (uriList.size() <= id) {
					String value = readString();
					uri = resolve(URI.createURI(value));
					uriList.add(uri);
				} else {
					uri = uriList.get(id);
				}
				String fragment = readString();
				if (fragment != null) {
					uri = uri.appendFragment(fragment);
				}
				return uri;
			}
		}
	}
}
