/**
 * <copyright>
 *
 * Copyright (c) 2014 itemis 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/org/documents/epl-2.0/EPL-2.0.html
 *
 * Contributors:
 *     itemis - Initial API and implementation
 *
 * </copyright>
 */
package org.eclipse.sphinx.emf.serialization.internal;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.xerces.impl.Constants;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClassifier;
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.URIConverter;
import org.eclipse.emf.ecore.util.ExtendedMetaData;
import org.eclipse.emf.ecore.xmi.ClassNotFoundException;
import org.eclipse.emf.ecore.xmi.FeatureNotFoundException;
import org.eclipse.emf.ecore.xmi.XMLHelper;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.ecore.xmi.impl.SAXXMLHandler;
import org.eclipse.emf.ecore.xmi.impl.XMLHandler;
import org.eclipse.emf.ecore.xml.type.AnyType;
import org.eclipse.sphinx.emf.serialization.XMLPersistenceMappingExtendedMetaData;
import org.eclipse.sphinx.emf.serialization.XMLPersistenceMappingExtendedMetaDataImpl;
import org.eclipse.sphinx.emf.serialization.XMLPersistenceMappingResource;

// TODO: add javadoc for each state chart
// TODO: add pool that reuses loadpatterns (reduces GC overhead)
// TODO: assert that extended metadata is available.
// TODO: assert that xmlMap is never used
// TODO: check for correct handling of types, object stacks.
// TODO: consider using symboltyble and replace .equals by ==
// TODO: create assertions in case the Handler is not used corretly. e.g. extennded metadata has incorrect format
// TODO: log info if options are used that are not supported
public class XMLPersistenceMappingHandler extends SAXXMLHandler {
	protected String typeAttributeName = null;

	protected XMLPersistenceMappingExtendedMetaData xmlPersistenceMappingExtendedMetaData = null;
	protected MyStack<LoadPattern> loadPatternStack = null;

	IProgressMonitor progressMonitor = null;
	int progressMonitorChunksRead = 0;
	int progressMonitorChunkSize = 2048;
	int progressMonitorLastStartInChunk = 0;
	int progressMonitorNumberOfChunksPerUpdate = 500;

	protected interface LoadPattern {
		public static int STATE_READY = 0;
		public static int STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT = 1;
		public static int STATE_HAS_SEEN_START_FEATURE_ELEMENT = 2;
		public static int STATE_HAS_SEEN_START_CLASSIFIER_WRAPPER_ELEMENT = 3;
		public static int STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT = 4;
		public static int STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT = 5;
		public static int STATE_HAS_SEEN_END_FEATURE_ELEMENT = 6;
		public static int STATE_HAS_SEEN_END_CLASSIFIER_WRAPPER_ELEMENT = 7;
		public static int STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT = 8;
		public static int STATE_DELEGATE_CHILD_NEEDED = -1;
		public static int STATE_DELEGATE_PARENT_NEEDED = -2;
		public static int STATE_DELEGATE_SIBLING_NEEDED = -3;

		public static int STATE_UNEXPECTED_ELEMENT = -100;

		void startElement(String namespace, String xmlName);

		void endElement(String namespace, String xmlName);

		boolean needsDelegateChild();

		boolean needsDelegateSibling();

		boolean needsDelegateParent();

	}

	protected abstract class AbstractLoadPatternImpl implements LoadPattern {
		protected final EObject anchorEObject;
		protected final EStructuralFeature feature;
		protected int currentState;

		public AbstractLoadPatternImpl(EObject anchorEObject, EStructuralFeature feature) {
			this.anchorEObject = anchorEObject;
			this.feature = feature;
			currentState = STATE_READY;
		}

		@Override
		public boolean needsDelegateChild() {
			return STATE_DELEGATE_CHILD_NEEDED == currentState;
		}

		@Override
		public boolean needsDelegateParent() {
			return STATE_DELEGATE_PARENT_NEEDED == currentState;
		}

		@Override
		public boolean needsDelegateSibling() {
			return STATE_DELEGATE_SIBLING_NEEDED == currentState;
		}

	}

	protected class LoadPatternEReferenceContained0001Impl extends AbstractLoadPatternImpl {
		String classifierName = null;

		public LoadPatternEReferenceContained0001Impl(EObject anchorEObject, EStructuralFeature feature) {
			super(anchorEObject, feature);
		}

		@Override
		public void startElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
				classifierName = xmlName;
				createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
				break;
			case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
				currentState = STATE_DELEGATE_CHILD_NEEDED;
				break;
			case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
				if (xmlName.equals(classifierName)) {
					currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
					createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
				} else {
					currentState = STATE_DELEGATE_SIBLING_NEEDED;
				}
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		@Override
		public void endElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
				// this happens if there are no nested structures
				handleEndCreateObjectElement();
				currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_DELEGATE_CHILD_NEEDED:
				// this happens if there are nested structures
				handleEndCreateObjectElement();
				currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	protected class LoadPatternEReferenceContained0100Impl extends AbstractLoadPatternImpl {
		String featureName;

		public LoadPatternEReferenceContained0100Impl(EObject anchorEObject, EStructuralFeature feature) {
			super(anchorEObject, feature);
		}

		@Override
		public void startElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
				featureName = xmlName;
				// This puts the newly created eObject onto the objects stack
				createObject(anchorEObject, feature);
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				currentState = STATE_DELEGATE_CHILD_NEEDED;
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				if (featureName.equals(xmlName)) {
					currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
					createObject(anchorEObject, feature);
				} else {
					currentState = STATE_DELEGATE_SIBLING_NEEDED;
				}

				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		@Override
		public void endElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				handleEndCreateObjectElement();
				currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_DELEGATE_CHILD_NEEDED:
				handleEndCreateObjectElement();
				currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	protected class LoadPatternEReferenceContained0101Impl extends AbstractLoadPatternImpl {
		String featureName = null;

		public LoadPatternEReferenceContained0101Impl(EObject anchorEObject, EStructuralFeature feature) {
			super(anchorEObject, feature);
		}

		@Override
		public void startElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				featureName = xmlName;
				currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;

				createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
				break;
			case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
				currentState = STATE_DELEGATE_CHILD_NEEDED;
				break;
			case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
				// for robustness: we allow multiple classiefier elements in a feature element. a warning should be
				// created
				currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
				createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				if (featureName.equals(xmlName)) {
					currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
				} else {
					currentState = STATE_DELEGATE_SIBLING_NEEDED;
				}
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		@Override
		public void endElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				// only the feature element was available => consider it as a null value;

				if (feature.isMany()) {
					@SuppressWarnings("unchecked")
					EList<EObject> values = (EList<EObject>) anchorEObject.eGet(feature);
					values.clear();
				} else {
					setFeatureValue(anchorEObject, feature, null);
				}
				currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				break;
			case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
				handleEndCreateObjectElement();
				currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
				currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_DELEGATE_CHILD_NEEDED:
				handleEndCreateObjectElement();
				currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	protected class LoadPatternEReferenceContained1001Impl extends AbstractLoadPatternImpl {
		String featureWrapperName = null;

		public LoadPatternEReferenceContained1001Impl(EObject anchorEObject, EStructuralFeature feature) {
			super(anchorEObject, feature);
		}

		@Override
		public void startElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				featureWrapperName = xmlName;
				currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
				break;
			case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
				currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
				createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
				break;
			case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
				currentState = STATE_DELEGATE_CHILD_NEEDED;
				break;
			case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
				currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
				createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
				break;
			case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
				if (featureWrapperName.equals(xmlName)) {
					currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
				} else {
					currentState = STATE_DELEGATE_SIBLING_NEEDED;
				}
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		@Override
		public void endElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
				// only the feature element was available => consider it as a null value;
				if (feature.isMany()) {
					@SuppressWarnings("unchecked")
					EList<EObject> values = (EList<EObject>) anchorEObject.eGet(feature);
					values.clear();
				} else {
					setFeatureValue(anchorEObject, feature, null);
				}
				currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
				break;
			case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
				handleEndCreateObjectElement();
				currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
				currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_DELEGATE_CHILD_NEEDED:
				handleEndCreateObjectElement();
				currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	/**
	 * This class implements.... <img src="doc-files/LoadPatternEAttributeContained0100.png">
	 */
	protected class LoadPatternEAttributeContained0100Impl extends AbstractLoadPatternImpl {
		String featureName = null;
		int depthsOfUnknownElements = 0;
		String value = null;

		public LoadPatternEAttributeContained0100Impl(EObject anchorEObject, EStructuralFeature feature) {
			super(anchorEObject, feature);
		}

		@Override
		public void startElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
				featureName = xmlName;
				types.push(feature);
				if (!isNull()) {
					text = new StringBuffer();
				}
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				currentState = STATE_UNEXPECTED_ELEMENT;
				depthsOfUnknownElements = 1;
				types.push(ERROR_TYPE);
				error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
				break;
			case STATE_UNEXPECTED_ELEMENT:
				depthsOfUnknownElements++;
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				if (featureName.equals(xmlName)) {
					text = new StringBuffer(); // record all strings
					currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
					// wait to read contained text
				} else {
					currentState = STATE_DELEGATE_SIBLING_NEEDED;
				}
				break;

			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		@Override
		public void endElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				if (isNull()) {
					setFeatureValue(anchorEObject, feature, null);
				} else {
					setFeatureValue(anchorEObject, feature, text == null ? null : text.toString());
				}
				text = null;
				currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_UNEXPECTED_ELEMENT:
				depthsOfUnknownElements--;
				if (0 > depthsOfUnknownElements) {
					currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				}
				break;
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	protected class LoadPatternEReferenceContained1100Impl extends AbstractLoadPatternImpl {
		String featureWrapperName = null;

		public LoadPatternEReferenceContained1100Impl(EObject anchorEObject, EStructuralFeature feature) {
			super(anchorEObject, feature);
		}

		@Override
		public void startElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				featureWrapperName = xmlName;
				currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
				break;
			case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
				currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
				// This puts the newly created eObject onto the objects stack
				createObject(anchorEObject, feature);
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				currentState = STATE_DELEGATE_CHILD_NEEDED;
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
				createObject(anchorEObject, feature);
				break;
			case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
				if (featureWrapperName.equals(xmlName)) {
					currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
				} else {
					currentState = STATE_DELEGATE_SIBLING_NEEDED;
				}
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		@Override
		public void endElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
				// only the feature element was available => consider it as a null value;
				if (feature.isMany()) {
					@SuppressWarnings("unchecked")
					EList<EObject> values = (EList<EObject>) anchorEObject.eGet(feature);
					values.clear();
				} else {
					setFeatureValue(anchorEObject, feature, null);
				}
				currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				handleEndCreateObjectElement();
				currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_DELEGATE_CHILD_NEEDED:
				handleEndCreateObjectElement();
				currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	protected class LoadPatternEAttributeContained1000Impl extends AbstractLoadPatternImpl {
		String featureWrapperName = null;
		int depthsOfUnknownElements = 0;

		public LoadPatternEAttributeContained1000Impl(EObject anchorEObject, EStructuralFeature feature) {
			super(anchorEObject, feature);
		}

		@Override
		public void startElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
				featureWrapperName = xmlName;
				text = new StringBuffer(); // record all strings
				break;
			case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
				currentState = STATE_UNEXPECTED_ELEMENT;
				depthsOfUnknownElements = 1;
				types.push(ERROR_TYPE);
				error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
				break;
			case STATE_UNEXPECTED_ELEMENT:
				depthsOfUnknownElements++;
				break;
			case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
				if (featureWrapperName.equals(xmlName)) {
					currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
					text = new StringBuffer(); // record all strings
					// wait to read contained text
				} else {
					currentState = STATE_DELEGATE_SIBLING_NEEDED;
				}
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		@Override
		public void endElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
				if (null == text) {
					setFeatureValue(anchorEObject, feature, null);
				} else {
					String svalues = text.toString();
					StringTokenizer st = new StringTokenizer(svalues);
					String svalue;
					while (st.hasMoreTokens()) {
						svalue = st.nextToken();
						setFeatureValue(anchorEObject, feature, svalue);
					}
				}
				text = null;
				currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_UNEXPECTED_ELEMENT:
				depthsOfUnknownElements--;
				if (0 > depthsOfUnknownElements) {
					currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
				}
				break;
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	protected class LoadPatternEAttributeContained1100Impl extends AbstractLoadPatternImpl {
		String featureWrapperName = null;
		int depthsOfUnknownElements = 0;

		public LoadPatternEAttributeContained1100Impl(EObject anchorEObject, EStructuralFeature feature) {
			super(anchorEObject, feature);
		}

		@Override
		public void startElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				featureWrapperName = xmlName;
				currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
				break;
			case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
				currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
				text = new StringBuffer(); // record all strings
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				currentState = STATE_UNEXPECTED_ELEMENT;
				depthsOfUnknownElements = 1;
				types.push(ERROR_TYPE);
				error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
				break;
			case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
				if (featureWrapperName == xmlName) {
					currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
				} else {
					currentState = STATE_DELEGATE_SIBLING_NEEDED;
				}
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
				text = new StringBuffer(); // record all strings
				break;
			case STATE_UNEXPECTED_ELEMENT:
				depthsOfUnknownElements++;
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		@Override
		public void endElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
				currentState = STATE_READY;
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				setFeatureValue(anchorEObject, feature, text == null ? null : text.toString());
				text = null;
				currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
				break;
			case STATE_UNEXPECTED_ELEMENT:
				depthsOfUnknownElements--;
				if (0 > depthsOfUnknownElements) {
					currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				}
				break;
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	protected class LoadPatternEReferenceReferenced0100Impl extends AbstractLoadPatternImpl {
		String featureName = null;
		InternalEObject proxy;
		int depthsOfUnknownElements = 0;

		public LoadPatternEReferenceReferenced0100Impl(EObject anchorEObject, EStructuralFeature feature) {
			super(anchorEObject, feature);
		}

		@Override
		public void startElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
				createObject(anchorEObject, feature);
				proxy = (InternalEObject) objects.peekEObject();
				text = new StringBuffer(); // record all strings
				featureName = xmlName;
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				currentState = STATE_UNEXPECTED_ELEMENT;
				depthsOfUnknownElements = 1;
				types.push(ERROR_TYPE);
				error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				if (featureName.equals(xmlName)) {
					currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
					createObject(anchorEObject, feature);
					proxy = (InternalEObject) objects.peekEObject();
					text = new StringBuffer(); // record all strings
				} else {
					currentState = STATE_DELEGATE_SIBLING_NEEDED;
				}
				break;
			case STATE_UNEXPECTED_ELEMENT:
				depthsOfUnknownElements++;
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		@Override
		public void endElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				if (null != proxy) {
					handleProxy(proxy, resourceURI.toString() + "#" + text.toString()); //$NON-NLS-1$
					objects.pop();
					mixedTargets.pop();
				} else {
					// NOP: error already handled during startElement()
				}

				text = null;
				currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_UNEXPECTED_ELEMENT:
				depthsOfUnknownElements--;
				if (0 > depthsOfUnknownElements) {
					currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				}
				break;
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	protected class LoadPatternEReferenceReferenced0101Impl extends AbstractLoadPatternImpl {
		String featureName = null;
		InternalEObject proxy = null;
		int depthsOfUnknownElements = 0;

		public LoadPatternEReferenceReferenced0101Impl(EObject anchorEObject, EStructuralFeature feature) {
			super(anchorEObject, feature);
		}

		@Override
		public void startElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				featureName = xmlName;
				currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
				proxy = (InternalEObject) createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
				text = new StringBuffer(); // record all strings
				break;
			case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
				currentState = STATE_UNEXPECTED_ELEMENT;
				depthsOfUnknownElements = 1;
				types.push(ERROR_TYPE);
				error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
				break;
			case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
				// for robustness: we allow multiple classifier elements in a feature element. a warning should be
				// created
				proxy = (InternalEObject) createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
				currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
				text = new StringBuffer(); // record all strings
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				if (featureName.equals(xmlName)) {
					currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
				} else {
					currentState = STATE_DELEGATE_SIBLING_NEEDED;
				}
				break;
			case STATE_UNEXPECTED_ELEMENT:
				depthsOfUnknownElements++;
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		@Override
		public void endElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				break;
			case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
				if (null != proxy) {
					handleProxy(proxy, resourceURI.toString() + "#" + text.toString()); //$NON-NLS-1$
					objects.pop();
					mixedTargets.pop();
				} else {
					// NOP: error already handled during startElement
				}
				text = null;
				currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
				currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_UNEXPECTED_ELEMENT:
				depthsOfUnknownElements--;
				if (0 > depthsOfUnknownElements) {
					currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
				}
				break;
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	protected class LoadPatternEReferenceReferenced1001Impl extends AbstractLoadPatternImpl {
		InternalEObject proxy = null;
		String featureWrapperName = null;
		int depthsOfUnknownElements = 0;

		public LoadPatternEReferenceReferenced1001Impl(EObject anchorEObject, EStructuralFeature feature) {
			super(anchorEObject, feature);
		}

		@Override
		public void startElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				featureWrapperName = xmlName;
				currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
				break;
			case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
				currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
				proxy = (InternalEObject) createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
				text = new StringBuffer(); // record all strings
				break;
			case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
				currentState = STATE_UNEXPECTED_ELEMENT;
				depthsOfUnknownElements = 1;
				types.push(ERROR_TYPE);
				error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
				break;
			case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
				// for robustness: we allow multiple classiefier elements in a feature element. a warning should be
				// created
				currentState = STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT;
				proxy = (InternalEObject) createObjectFromNamespaceAndType(anchorEObject, feature, namespace, xmlName);
				text = new StringBuffer(); // record all strings
				break;
			case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
				if (featureWrapperName.equals(xmlName)) {
					currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
				} else {
					currentState = STATE_DELEGATE_SIBLING_NEEDED;
				}
				break;
			case STATE_UNEXPECTED_ELEMENT:
				depthsOfUnknownElements++;
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		@Override
		public void endElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
				// only the feature element was available => consider it as a null value;
				if (feature.isMany()) {
					@SuppressWarnings("unchecked")
					EList<EObject> values = (EList<EObject>) anchorEObject.eGet(feature);
					values.clear();
				} else {
					setFeatureValue(anchorEObject, feature, null);
				}
				currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
				break;
			case STATE_HAS_SEEN_START_CLASSIFIER_ELEMENT:
				if (null != proxy) {
					objects.pop();
					mixedTargets.pop();
					handleProxy(proxy, resourceURI.toString() + "#" + text.toString()); //$NON-NLS-1$
				}

				text = null;
				currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT:
				currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_UNEXPECTED_ELEMENT:
				depthsOfUnknownElements--;
				if (0 > depthsOfUnknownElements) {
					currentState = STATE_HAS_SEEN_END_CLASSIFIER_ELEMENT;
				}
				break;
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	protected class LoadPatternEReferenceReferenced1100Impl extends AbstractLoadPatternImpl {
		String featureWrapperName = null;
		InternalEObject proxy = null;
		int depthsOfUnknownElements = 0;

		public LoadPatternEReferenceReferenced1100Impl(EObject anchorEObject, EStructuralFeature feature) {
			super(anchorEObject, feature);
		}

		@Override
		public void startElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				featureWrapperName = xmlName;
				currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
				break;
			case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
				currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
				createObject(anchorEObject, feature);
				proxy = (InternalEObject) objects.peekEObject();
				text = new StringBuffer(); // record all strings
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				currentState = STATE_UNEXPECTED_ELEMENT;
				depthsOfUnknownElements = 1;
				types.push(ERROR_TYPE);
				error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
				break;
			case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
				if (featureWrapperName.equals(xmlName)) {
					currentState = STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT;
				} else {
					currentState = STATE_DELEGATE_SIBLING_NEEDED;
				}
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				currentState = STATE_HAS_SEEN_START_FEATURE_ELEMENT;
				createObject(anchorEObject, feature);
				proxy = (InternalEObject) objects.peekEObject();
				text = new StringBuffer(); // record all strings
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		@Override
		public void endElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_HAS_SEEN_START_FEATURE_WRAPPER_ELEMENT:
				// only the feature element was available => consider it as a null value;
				if (feature.isMany()) {
					@SuppressWarnings("unchecked")
					EList<EObject> values = (EList<EObject>) anchorEObject.eGet(feature);
					values.clear();
				} else {
					setFeatureValue(anchorEObject, feature, null);
				}
				currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
				break;
			case STATE_HAS_SEEN_START_FEATURE_ELEMENT:
				if (null != proxy) {
					handleProxy((InternalEObject) objects.peekEObject(), resourceURI.toString() + "#" + text.toString()); //$NON-NLS-1$
					objects.pop();
					mixedTargets.pop();
				}
				text = null;
				currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				break;
			case STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_HAS_SEEN_END_FEATURE_ELEMENT:
				currentState = STATE_HAS_SEEN_END_FEATURE_WRAPPER_ELEMENT;
				break;
			case STATE_UNEXPECTED_ELEMENT:
				depthsOfUnknownElements--;
				if (0 > depthsOfUnknownElements) {
					currentState = STATE_HAS_SEEN_END_FEATURE_ELEMENT;
				}
				break;
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	protected class LoadPatternUnknownImpl extends AbstractLoadPatternImpl {
		int depthsOfUnknownElements = 0;

		public LoadPatternUnknownImpl(EObject anchorEObject, EStructuralFeature feature) {
			super(anchorEObject, feature);
		}

		@Override
		public void startElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_UNEXPECTED_ELEMENT;
				depthsOfUnknownElements = 1;
				types.push(ERROR_TYPE);
				error(new FeatureNotFoundException(xmlName, null, getLocation(), getLineNumber(), getColumnNumber()));
				break;
			case STATE_UNEXPECTED_ELEMENT:
				depthsOfUnknownElements++;
				break;
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		@Override
		public void endElement(String namespace, String xmlName) {
			switch (currentState) {
			case STATE_READY:
				currentState = STATE_DELEGATE_PARENT_NEEDED;
				break;
			case STATE_UNEXPECTED_ELEMENT:
				depthsOfUnknownElements--;
				if (0 > depthsOfUnknownElements) {
					currentState = STATE_DELEGATE_PARENT_NEEDED;
				}
				break;
			case STATE_DELEGATE_CHILD_NEEDED:
			case STATE_DELEGATE_SIBLING_NEEDED:
			case STATE_DELEGATE_PARENT_NEEDED:
				assert false : "handshake error: the dispatcher should have switched to another load pattern instance (state=" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
				break;
			default:
				assert false : "state machine error: unsupported state (state =" + currentState + ", startElement)"; //$NON-NLS-1$ //$NON-NLS-2$
			}
		}
	}

	public XMLPersistenceMappingHandler(XMLResource xmlResource, XMLHelper helper, Map<?, ?> options) {
		super(xmlResource, helper, options);

		// set extended meta data
		Object extendedMetaDataOption = options.get(XMLResource.OPTION_EXTENDED_META_DATA);
		if (null != extendedMetaDataOption && extendedMetaDataOption instanceof XMLPersistenceMappingExtendedMetaData) {
			xmlPersistenceMappingExtendedMetaData = (XMLPersistenceMappingExtendedMetaData) options.get(XMLResource.OPTION_EXTENDED_META_DATA);
			extendedMetaData = xmlPersistenceMappingExtendedMetaData;
		} else {
			// default
			xmlPersistenceMappingExtendedMetaData = xmlResource == null || xmlResource.getResourceSet() == null ? XMLPersistenceMappingExtendedMetaData.INSTANCE
					: new XMLPersistenceMappingExtendedMetaDataImpl(xmlResource.getResourceSet().getPackageRegistry());
			extendedMetaData = xmlPersistenceMappingExtendedMetaData;
		}
		helper.setExtendedMetaData(xmlPersistenceMappingExtendedMetaData);

		// initialize progress monitor
		Object progressMonitor = options.get(XMLPersistenceMappingResource.OPTION_PROGRESS_MONITOR);
		if (progressMonitor instanceof IProgressMonitor) {
			this.progressMonitor = (IProgressMonitor) progressMonitor;
		} else {
			// ignore
		}

		// get chunk size of xml parser, that is required for calculation of progress monitor ticks
		Object parserPropertiesObject = options.get(XMLResource.OPTION_PARSER_PROPERTIES);
		if (null != parserPropertiesObject && parserPropertiesObject instanceof Map<?, ?>) {
			@SuppressWarnings("unchecked")
			Map<String, Object> parserProperties = (Map<String, Object>) parserPropertiesObject;
			Object bufferSizeObject = parserProperties.get(Constants.XERCES_PROPERTY_PREFIX + Constants.BUFFER_SIZE_PROPERTY);
			if (bufferSizeObject instanceof Integer) {
				progressMonitorChunkSize = (Integer) bufferSizeObject;
			} else {
				// use default;
			}
		} else {
			// use default;
		}

		loadPatternStack = new MyStack<LoadPattern>();

		// redefine href attribute since e.g.:
		// xhtml.a.type/@href conflicts with this attribute and results in proxy resolution which can in turn
		// result in long delays during load.
		hrefAttribute = XMLPersistenceMappingResource.HREF;

		// postconditions
		assert null != xmlPersistenceMappingExtendedMetaData;
		assert null != extendedMetaData;

	}

	/**
	 * Create an object based on the given feature and attributes.
	 */
	protected EObject createObjectFromNamespaceAndType(EObject peekObject, EStructuralFeature feature, String namespace, String typeXMLName) {
		assert null != xmlPersistenceMappingExtendedMetaData;
		assert null != peekObject;
		assert null != feature;
		assert null != namespace;
		assert null != typeXMLName;

		// make sure, that information about feature is available for handleMissingPackage
		contextFeature = feature;
		EPackage ePackage = getPackageForURI(namespace);
		contextFeature = null;

		if (null != ePackage) {
			EClassifier eClassifier;
			if (xmlPersistenceMappingExtendedMetaData.demandedPackages().contains(ePackage)) {
				// demand package requires demand type
				eClassifier = xmlPersistenceMappingExtendedMetaData.demandType(namespace, typeXMLName);
			} else {
				eClassifier = xmlPersistenceMappingExtendedMetaData.getTypeByXMLName(namespace, typeXMLName, feature);
			}

			EFactory eFactory = ePackage.getEFactoryInstance();

			if (null != eClassifier) {
				EObject obj = createObject(eFactory, eClassifier, false);
				obj = validateCreateObjectFromFactory(eFactory, typeXMLName, obj, feature);
				if (obj != null) {
					setFeatureValue(peekObject, feature, obj);
					processObject(obj);
				}
				return obj;
			} else {
				error(new ClassNotFoundException(typeXMLName, eFactory, getLocation(), getLineNumber(), getColumnNumber()));
				return null;
			}

		} else {
			return null;
		}
	}

	@Override
	protected EObject validateCreateObjectFromFactory(EFactory factory, String typeName, EObject newObject, EStructuralFeature feature) {
		if (newObject != null) {
			if (extendedMetaData != null) {
				Collection<EPackage> demandedPackages = extendedMetaData.demandedPackages();
				if (!demandedPackages.isEmpty() && demandedPackages.contains(newObject.eClass().getEPackage())) {
					if (xmlPersistenceMappingExtendedMetaData.isXMLPersistenceMappingEnabled(feature)) {
						List<String> wildcards = xmlPersistenceMappingExtendedMetaData.getWildcards(feature);
						if (xmlPersistenceMappingExtendedMetaData.matches(wildcards, newObject.eClass().getEPackage().getNsURI())) {
							return newObject;
						} else {
							return null;
						}
					} else {
						// the new object resulted from a demanded package
						if (recordUnknownFeature) {
							// recordUnknownFeature
							EObject peekObject = objects.peekEObject();
							if (!(peekObject instanceof AnyType)) {
								AnyType anyType = getExtension(objects.peekEObject());
								EStructuralFeature entryFeature = extendedMetaData.demandFeature(extendedMetaData.getNamespace(feature),
										extendedMetaData.getName(feature), true);
								anyType.getAny().add(entryFeature, newObject);
								contextFeature = entryFeature;
							}
							return newObject;
						} else {
							// reportUnknowFeature
							String namespace = extendedMetaData.getNamespace(feature);
							String name = extendedMetaData.getName(feature);
							EStructuralFeature wildcardFeature = extendedMetaData.getElementWildcardAffiliation(objects.peekEObject().eClass(),
									namespace, name);
							if (wildcardFeature != null) {
								int processingKind = laxWildcardProcessing ? ExtendedMetaData.LAX_PROCESSING : extendedMetaData
										.getProcessingKind(wildcardFeature);
								switch (processingKind) {
								case ExtendedMetaData.LAX_PROCESSING:
								case ExtendedMetaData.SKIP_PROCESSING: {
									return newObject;
								}
								}
							}
						}

						newObject = null;
					}
				}
			}
		} else if (feature != null && factory != null && extendedMetaData != null) {
			// processing unknown feature with xsi:type (xmi:type)
			if (recordUnknownFeature || processAnyXML) {

				EObject result = null;
				String namespace = extendedMetaData.getNamespace(factory.getEPackage());
				if (namespace == null) {
					usedNullNamespacePackage = true;
				}

				EClassifier type = extendedMetaData.demandType(namespace, typeName);
				result = createObject(type.getEPackage().getEFactoryInstance(), type, false);

				EObject peekObject = objects.peekEObject();
				if (!(peekObject instanceof AnyType)) {
					// add as extension to an existing eobject
					AnyType anyType = getExtension(peekObject);
					EStructuralFeature entryFeature = extendedMetaData.demandFeature(extendedMetaData.getNamespace(feature),
							extendedMetaData.getName(feature), true);
					anyType.getAny().add(entryFeature, result);
					contextFeature = entryFeature;
				}
				return result;
			} else {
				String namespace = extendedMetaData.getNamespace(feature);
				String name = extendedMetaData.getName(feature);
				EStructuralFeature wildcardFeature = extendedMetaData.getElementWildcardAffiliation(objects.peekEObject().eClass(), namespace, name);
				if (wildcardFeature != null) {
					int processingKind = laxWildcardProcessing ? ExtendedMetaData.LAX_PROCESSING : extendedMetaData
							.getProcessingKind(wildcardFeature);
					switch (processingKind) {
					case ExtendedMetaData.LAX_PROCESSING:
					case ExtendedMetaData.SKIP_PROCESSING: {
						// EATM Demand create metadata; needs to depend on processing mode...
						String factoryNamespace = extendedMetaData.getNamespace(factory.getEPackage());
						if (factoryNamespace == null) {
							usedNullNamespacePackage = true;
						}
						EClassifier type = extendedMetaData.demandType(factoryNamespace, typeName);
						return createObject(type.getEPackage().getEFactoryInstance(), type, false);
					}
					}
				}
			}
		}

		validateCreateObjectFromFactory(factory, typeName, newObject);

		return newObject;
	}

	@Override
	public void characters(char[] ch, int start, int length) {
		super.characters(ch, start, length);
		if (null != progressMonitor) {
			if (start < progressMonitorLastStartInChunk) {
				progressMonitorChunksRead += 1;
			}
			if (progressMonitorChunksRead > progressMonitorNumberOfChunksPerUpdate) {
				progressMonitor.worked(progressMonitorChunksRead);
				progressMonitorChunksRead = 0;
			}
			progressMonitorLastStartInChunk = start;
		}
	}

	@Override
	public void endElement(String uri, String localName, String qName) {
		if (null != xmlPersistenceMappingExtendedMetaData) {
			elements.pop();
			types.pop();

			helper.popContext(prefixesToFactories);

			// end from super.endElement

			LoadPattern activeDeserializationRule = loadPatternStack.peek();
			if (null != activeDeserializationRule) {
				activeDeserializationRule.endElement(uri, localName);
				if (activeDeserializationRule.needsDelegateParent()) {
					loadPatternStack.pop();
					activeDeserializationRule = loadPatternStack.peek();
					if (null != activeDeserializationRule) {
						// this happens if we return to the root object
						activeDeserializationRule.endElement(uri, localName);
					}
				}
			}
		} else {
			super.endElement(uri, localName, qName);
		}
	}

	/**
	 * The XML element represents a feature. There are two cases to handle: 1. The feature has a type that is a
	 * datatype. 2. The feature has a type that is a class.
	 */
	@Override
	protected void handleFeature(String prefix, String name) {
		assert useNewMethods == true;
		EObject peekObject = objects.peekEObject();

		// This happens when processing an element with simple content that has elements content even though it
		// shouldn't.
		//
		if (peekObject == null) {
			types.push(ERROR_TYPE);
			error(new FeatureNotFoundException(name, null, getLocation(), getLineNumber(), getColumnNumber()));
			return;
		}

		if (null != xmlPersistenceMappingExtendedMetaData) {
			String namespace = helper.getNamespaceURI(prefix);
			LoadPattern activeDeserializationRule = loadPatternStack.peek();
			if (null == activeDeserializationRule) {
				activeDeserializationRule = getLoadPattern(peekObject, prefix, name);
				assert null != activeDeserializationRule : "getLoadPattern() should never return null"; //$NON-NLS-1$
				loadPatternStack.push(activeDeserializationRule);
			}

			if (null != activeDeserializationRule) {
				activeDeserializationRule.startElement(namespace, name);
				if (activeDeserializationRule.needsDelegateChild()) {
					activeDeserializationRule = getLoadPattern(peekObject, prefix, name);
					assert null != activeDeserializationRule : "getLoadPattern() should never return null"; //$NON-NLS-1$
					loadPatternStack.push(activeDeserializationRule);
					activeDeserializationRule.startElement(namespace, name);
				} else if (activeDeserializationRule.needsDelegateSibling()) {
					activeDeserializationRule = getLoadPattern(peekObject, prefix, name);
					assert null != activeDeserializationRule : "getLoadPattern() should never return null"; //$NON-NLS-1$
					loadPatternStack.pop();
					loadPatternStack.push(activeDeserializationRule);
					activeDeserializationRule.startElement(namespace, name);
				} else {
					// normal operation, no need for switching to another load pattern
				}

			}

		} else {
			EStructuralFeature feature = getFeature(peekObject, prefix, name, true);
			if (feature != null) {
				int kind = helper.getFeatureKind(feature);
				if (kind == XMLHelper.DATATYPE_SINGLE || kind == XMLHelper.DATATYPE_IS_MANY) {
					objects.push(null);
					mixedTargets.push(null);
					types.push(feature);
					if (!isNull()) {
						text = new StringBuffer();
					}
				} else if (extendedMetaData != null) {
					EReference eReference = (EReference) feature;
					boolean isContainment = eReference.isContainment();
					if (!isContainment && !eReference.isResolveProxies()
							&& extendedMetaData.getFeatureKind(feature) != ExtendedMetaData.UNSPECIFIED_FEATURE) {
						isIDREF = true;
						objects.push(null);
						mixedTargets.push(null);
						types.push(feature);
						text = new StringBuffer();
					} else {
						createObject(peekObject, feature);
						// child object is put on top of objects stack
						// if an error occured, then types.peek is ERROR
						//
						EObject childObject = objects.peekEObject();
						if (childObject != null) {
							if (isContainment) {
								EStructuralFeature simpleFeature = extendedMetaData.getSimpleFeature(childObject.eClass());
								if (simpleFeature != null) {
									isSimpleFeature = true;
									isIDREF = simpleFeature instanceof EReference;
									objects.push(null);
									mixedTargets.push(null);
									types.push(simpleFeature);
									text = new StringBuffer();
								}
							} else if (!childObject.eIsProxy()) {
								text = new StringBuffer();
							}
						}
					}
				} else {
					createObject(peekObject, feature);
				}
			} else {
				// Try to get a general-content feature.
				// Use a pattern that's not possible any other way.
				//
				if (xmlMap != null && (feature = getFeature(peekObject, null, "", true)) != null) { //$NON-NLS-1$

					EFactory eFactory = getFactoryForPrefix(prefix);

					// This is for the case for a local unqualified element that has been bound.
					//
					if (eFactory == null) {
						eFactory = feature.getEContainingClass().getEPackage().getEFactoryInstance();
					}

					EObject newObject = null;
					newObject = createObject(eFactory, helper.getType(eFactory, name), false);
					newObject = validateCreateObjectFromFactory(eFactory, name, newObject, feature);
					if (newObject != null) {
						setFeatureValue(peekObject, feature, newObject);
					}
					processObject(newObject);
				} else {
					// This handles the case of a substitution group.
					//
					if (xmlMap != null) {
						EFactory eFactory = getFactoryForPrefix(prefix);
						@SuppressWarnings("deprecation")
						EObject newObject = createObjectFromFactory(eFactory, name);
						validateCreateObjectFromFactory(eFactory, name, newObject);
						if (newObject != null) {
							for (EReference eReference : peekObject.eClass().getEAllReferences()) {
								if (eReference.getEType().isInstance(newObject)) {
									setFeatureValue(peekObject, eReference, newObject);
									processObject(newObject);
									return;
								}
							}
						}
					}

					handleUnknownFeature(prefix, name, true, peekObject, null);
				}
			}
		}
	}

	protected LoadPattern getLoadPattern(EObject eObject, String prefix, String name) {
		assert null != xmlPersistenceMappingExtendedMetaData;

		LoadPattern deserializationRule = null;

		if (eObject instanceof AnyType) {
			// handle any type using standard emf serialization
			EStructuralFeature feature = super.getFeature(eObject, prefix, name, true);
			deserializationRule = new LoadPatternEReferenceContained0100Impl(eObject, feature);
		} else {
			EStructuralFeature feature = getFeature(eObject, prefix, name, true);
			if (null != feature) {
				int persistenceMappingStrategy = xmlPersistenceMappingExtendedMetaData.getXMLPersistenceMappingStrategy(feature);
				if (feature instanceof EReference) {
					EReference reference = (EReference) feature;
					if (reference.isContainment()) {
						switch (persistenceMappingStrategy) {
						case XMLPersistenceMappingExtendedMetaData.XML_PERSISTENCE_MAPPING_STRATEGY__0001__CLASSIFIER_ELEMENT:
							deserializationRule = new LoadPatternEReferenceContained0001Impl(eObject, feature);
							break;
						case XMLPersistenceMappingExtendedMetaData.XML_PERSISTENCE_MAPPING_STRATEGY__0100__FEATURE_ELEMENT:
							deserializationRule = new LoadPatternEReferenceContained0100Impl(eObject, feature);
							break;
						case XMLPersistenceMappingExtendedMetaData.XML_PERSISTENCE_MAPPING_STRATEGY__0101__FEATURE_ELEMENT__CLASSIFIER_ELEMENT:
							deserializationRule = new LoadPatternEReferenceContained0101Impl(eObject, feature);
							break;
						case XMLPersistenceMappingExtendedMetaData.XML_PERSISTENCE_MAPPING_STRATEGY__1100__FEATURE_WRAPPER_ELEMENT__FEATURE_ELEMENT:
							deserializationRule = new LoadPatternEReferenceContained1100Impl(eObject, feature);
							break;
						case XMLPersistenceMappingExtendedMetaData.XML_PERSISTENCE_MAPPING_STRATEGY__1001__FEATURE_WRAPPER_ELEMENT__CLASSIFIER_ELEMENT:
							deserializationRule = new LoadPatternEReferenceContained1001Impl(eObject, feature);
							break;
						case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__UNDEFINED:
							deserializationRule = new LoadPatternEReferenceContained0100Impl(eObject, feature);
							break;
						default:
							deserializationRule = new LoadPatternEReferenceContained1001Impl(eObject, feature);
							break;
						}
					} else {
						switch (persistenceMappingStrategy) {
						case XMLPersistenceMappingExtendedMetaData.XML_PERSISTENCE_MAPPING_STRATEGY__0100__FEATURE_ELEMENT:
							deserializationRule = new LoadPatternEReferenceReferenced0100Impl(eObject, feature);
							break;
						case XMLPersistenceMappingExtendedMetaData.XML_PERSISTENCE_MAPPING_STRATEGY__0101__FEATURE_ELEMENT__CLASSIFIER_ELEMENT:
							deserializationRule = new LoadPatternEReferenceReferenced0101Impl(eObject, feature);
							break;
						case XMLPersistenceMappingExtendedMetaData.XML_PERSISTENCE_MAPPING_STRATEGY__1001__FEATURE_WRAPPER_ELEMENT__CLASSIFIER_ELEMENT:
							deserializationRule = new LoadPatternEReferenceReferenced1001Impl(eObject, feature);
							break;
						case XMLPersistenceMappingExtendedMetaData.XML_PERSISTENCE_MAPPING_STRATEGY__1100__FEATURE_WRAPPER_ELEMENT__FEATURE_ELEMENT:
							deserializationRule = new LoadPatternEReferenceReferenced1100Impl(eObject, feature);
							break;
						case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__UNDEFINED:
							deserializationRule = new LoadPatternEReferenceReferenced0100Impl(eObject, feature);
							break;
						default:
							deserializationRule = new LoadPatternEReferenceReferenced1001Impl(eObject, feature);
							break;
						}
					}
				} else {
					// feature is an EAttribute
					switch (persistenceMappingStrategy) {
					case XMLPersistenceMappingExtendedMetaData.XML_PERSISTENCE_MAPPING_STRATEGY__0100__FEATURE_ELEMENT:
						deserializationRule = new LoadPatternEAttributeContained0100Impl(eObject, feature);
						break;
					case XMLPersistenceMappingExtendedMetaData.XML_PERSISTENCE_MAPPING_STRATEGY__1000__FEATURE_WRAPPER_ELEMENT:
						deserializationRule = new LoadPatternEAttributeContained1000Impl(eObject, feature);
						break;
					case XMLPersistenceMappingExtendedMetaData.XML_PERSISTENCE_MAPPING_STRATEGY__1100__FEATURE_WRAPPER_ELEMENT__FEATURE_ELEMENT:
						deserializationRule = new LoadPatternEAttributeContained1100Impl(eObject, feature);
						break;
					case XMLPersistenceMappingExtendedMetaData.SERIALIZATION_STRUCTURE__UNDEFINED:
						deserializationRule = new LoadPatternEAttributeContained0100Impl(eObject, feature);
						break;

					default:
						deserializationRule = new LoadPatternEAttributeContained0100Impl(eObject, feature);
						break;
					}

				}
			} else {
				deserializationRule = new LoadPatternUnknownImpl(eObject, feature);
			}
		}

		assert null != deserializationRule : "getLoadPattern() should always return a LoadPattern (!=null)"; //$NON-NLS-1$
		return deserializationRule;

	}

	@Override
	protected EStructuralFeature getFeature(EObject object, String prefix, String name, boolean isElement) {
		assert null != object;
		assert null != name;
		EStructuralFeature result = null;
		if (isElement && null != xmlPersistenceMappingExtendedMetaData) {
			String namespace = helper.getNamespaceURI(prefix);
			result = xmlPersistenceMappingExtendedMetaData.getFeatureByXMLElementName(object.eClass(), namespace, name);
		} else {
			result = super.getFeature(object, prefix, name, isElement);
		}
		return result;
	}

	@Override
	public void reset() {
		super.reset();
		loadPatternStack = null;
		hrefAttribute = XMLPersistenceMappingResource.HREF;
	};

	@Override
	public void prepare(XMLResource resource, XMLHelper helper, Map<?, ?> options) {
		super.prepare(resource, helper, options);
		loadPatternStack = new MyStack<LoadPattern>();
		// enforce use of new methods
		useNewMethods = true;
		typeAttributeName = null;
	}

	protected String getXSIType(EStructuralFeature f) {
		typeAttributeName = xmlPersistenceMappingExtendedMetaData.getXMLTypeAttributeName(f);
		if (null == typeAttributeName || XMLHandler.TYPE_ATTRIB.equals(typeAttributeName)) {
			return getXSIType();
		} else {
			String namespace = xmlPersistenceMappingExtendedMetaData.getNamespace(f);
			if (null == namespace) {
				namespace = f.getEContainingClass().getEPackage().getNsURI();
			}
			String xsiType = attribs.getValue(typeAttributeName);
			if (null == xsiType) {
				xsiType = attribs.getValue(namespace, typeAttributeName);
			}
			if (null != xsiType && !xsiType.contains(":")) { //$NON-NLS-1$
				String prefix = helper.getPrefix(namespace);
				if (null == prefix || !"".equals(prefix)) { //$NON-NLS-1$
					StringBuffer buffer = new StringBuffer();
					buffer.append(helper.getPrefix(namespace));
					buffer.append(":"); //$NON-NLS-1$
					buffer.append(xsiType);
					xsiType = buffer.toString();
				}
			}

			return xsiType;
		}
	}

	protected void handleEndCreateObjectElement() {
		if (text == null) {
			objects.pop();
			mixedTargets.pop();
		} else {
			EObject object = objects.popEObject();
			if (mixedTargets.peek() != null
					&& (object.eContainer() != null || suppressDocumentRoot || recordUnknownFeature
							&& (eObjectToExtensionMap.containsValue(object) || ((InternalEObject) object).eDirectResource() != null))) {
				handleMixedText();
				mixedTargets.pop();
			}
		}
	}

	@Override
	public void startDocument() {
		super.startDocument();
		// initialize the progress monitor
		if (null != progressMonitor) {
			progressMonitorChunksRead = 0;
			progressMonitorLastStartInChunk = 0;
			progressMonitor.beginTask("Reading resource '" + resourceURI + "'", getProgressMonitorTotalWork()); //$NON-NLS-1$ //$NON-NLS-2$
		}

	}

	@Override
	public void endDocument() {
		super.endDocument();
		// finalize the progress monitor
		if (null != progressMonitor) {
			progressMonitor.done();
		}
	}

	protected int getProgressMonitorTotalWork() {
		int totalWork = IProgressMonitor.UNKNOWN;
		URI uri = xmlResource.getURI();

		InputStream is = null;
		try {
			is = URIConverter.INSTANCE.createInputStream(uri);
			totalWork = is.available() / progressMonitorChunkSize;
		} catch (IOException ex) {
			// NOP
		} finally {
			if (null != is) {
				try {
					is.close();
				} catch (IOException ex) {
					// NOP
				}
			}
		}
		return totalWork;
	}

	@Override
	protected EPackage handleMissingPackage(String uriString) {
		if (null != contextFeature && null != xmlPersistenceMappingExtendedMetaData
				&& xmlPersistenceMappingExtendedMetaData.isXMLPersistenceMappingEnabled(contextFeature)) {
			return xmlPersistenceMappingExtendedMetaData.demandPackage(uriString);

		} else {
			return super.handleMissingPackage(uriString);
		}
	}

	@Override
	protected void createObject(EObject peekObject, EStructuralFeature feature) {
		if (isNull()) {
			setFeatureValue(peekObject, feature, null);
			objects.push(null);
			mixedTargets.push(null);
			types.push(OBJECT_TYPE);
		} else {
			String xsiType = getXSIType(feature);
			if (xsiType != null) {
				createObjectFromTypeName(peekObject, xsiType, feature);
			} else {
				createObjectFromFeatureType(peekObject, feature);
			}
		}
	}

	/**
	 * Create a feature with the given name for the given object with the given values.
	 */
	@Override
	protected void setAttribValue(EObject object, String name, String value) {
		int index = name.indexOf(':', 0);

		// We use null here instead of "" because an attribute without a prefix is considered to have the null target
		// namespace...
		String prefix = null;
		String localName = name;
		if (index != -1) {
			prefix = name.substring(0, index);
			localName = name.substring(index + 1);
		}
		EStructuralFeature feature = getFeature(object, prefix, localName, false);
		if (feature == null) {
			handleUnknownFeature(prefix, localName, false, object, value);
		} else {
			int kind = helper.getFeatureKind(feature);

			if (kind == XMLHelper.DATATYPE_SINGLE || kind == XMLHelper.DATATYPE_IS_MANY) {
				setFeatureValue(object, feature, value, -2);
			} else {
				setValueFromId(object, (EReference) feature, value);
			}
		}
	}

	/**
	 * Process the XML attributes for the newly created object.
	 */
	@Override
	protected void handleObjectAttribs(EObject obj) {
		if (attribs != null) {
			InternalEObject internalEObject = (InternalEObject) obj;
			for (int i = 0, size = attribs.getLength(); i < size; ++i) {
				String name = attribs.getQName(i);
				if (!name.equals(typeAttributeName)) {
					if (name.equals(idAttribute)) {
						xmlResource.setID(internalEObject, attribs.getValue(i));
					} else if (name.equals(hrefAttribute)
							&& (!recordUnknownFeature || types.peek() != UNKNOWN_FEATURE_TYPE || obj.eClass() != anyType)) {
						handleProxy(internalEObject, attribs.getValue(i));
					} else if (isNamespaceAware) {
						String namespace = attribs.getURI(i);
						if (!ExtendedMetaData.XSI_URI.equals(namespace)) {
							setAttribValue(obj, name, attribs.getValue(i));
						}
					} else if (!name.startsWith(XMLResource.XML_NS) && !notFeatures.contains(name)) {
						setAttribValue(obj, name, attribs.getValue(i));
					}
				}
			}
		}
	}

}
