/*******************************************************************************
 * Copyright (c) 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.bpel.common.extension.model.impl;

import java.util.AbstractCollection;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

import org.eclipse.bpel.common.extension.model.Extension;
import org.eclipse.bpel.common.extension.model.ExtensionMap;
import org.eclipse.bpel.common.extension.model.ExtensionmodelFactory;
import org.eclipse.bpel.common.extension.model.ExtensionmodelPackage;
import org.eclipse.bpel.common.extension.model.adapters.ExtendedObjectAdapter;
import org.eclipse.bpel.common.extension.model.adapters.ExtendedObjectUserAdapter;
import org.eclipse.bpel.common.extension.model.adapters.impl.ExtendedObjectAdapterImpl;
import org.eclipse.bpel.common.extension.model.adapters.impl.ExtendedObjectUserAdapterImpl;
import org.eclipse.bpel.common.extension.model.adapters.impl.ExtensionAdapterImpl;
import org.eclipse.bpel.common.extension.model.adapters.impl.ExtensionMapAdapterImpl;
import org.eclipse.bpel.common.extension.model.notify.ExtensionModelNotification;
import org.eclipse.bpel.common.extension.model.notify.impl.ExtensionModelNotificationImpl;
import org.eclipse.bpel.common.extension.model.util.ExtensionmodelAdapterFactory;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.impl.EObjectImpl;
import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;


/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Extension Set</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link org.eclipse.bpel.common.extension.model.impl.ExtensionMapImpl#getNamespace <em>Namespace</em>}</li>
 *   <li>{@link org.eclipse.bpel.common.extension.model.impl.ExtensionMapImpl#getExtensions <em>Extensions</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class ExtensionMapImpl extends EObjectImpl implements ExtensionMap  {
	/**
	 * The default value of the '{@link #getNamespace() <em>Namespace</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNamespace()
	 * @generated
	 * @ordered
	 */
	protected static final String NAMESPACE_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getNamespace() <em>Namespace</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getNamespace()
	 * @generated
	 * @ordered
	 */
	protected String namespace = NAMESPACE_EDEFAULT;

	/**
	 * The cached value of the '{@link #getExtensions() <em>Extensions</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getExtensions()
	 * @generated
	 * @ordered
	 */
	protected EList<Extension> extensions = null;
	
	/**
	 * The value of the user adapter if one has been instantiated via the initializeAdapter()
	 * method.  This attribute is not modeled as it is not required to 
	 * serialize its value.
	 * @customized
	 */
	private ExtendedObjectUserAdapter userAdapter = null;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected ExtensionMapImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return ExtensionmodelPackage.eINSTANCE.getExtensionMap();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String getNamespace() {
		return namespace;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setNamespace(String newNamespace) {
		String oldNamespace = namespace;
		namespace = newNamespace;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, ExtensionmodelPackage.EXTENSION_MAP__NAMESPACE, oldNamespace, namespace));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<Extension> getExtensions() {
		if (extensions == null) {
			extensions = new EObjectContainmentEList<Extension>(Extension.class, this, ExtensionmodelPackage.EXTENSION_MAP__EXTENSIONS);
		}
		return extensions;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @customized
	 */
	public void initializeAdapter() {
		ExtensionmodelAdapterFactory factory = new ExtensionmodelAdapterFactory();
		if (userAdapter == null)
			userAdapter = (ExtendedObjectUserAdapter)factory.createEObjectAdapter();
		
		userAdapter.setExtensionMap(this);
		
		Set<EObject> extendedObjects = this.keySet();
		
		for (Iterator<EObject> iter = extendedObjects.iterator(); iter.hasNext();) {
			EObject element = iter.next();
			adaptEObject(element,userAdapter);
		}
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, Class baseClass, NotificationChain msgs) {
		if (featureID >= 0) {
			switch (eDerivedStructuralFeatureID(featureID, baseClass)) {
				case ExtensionmodelPackage.EXTENSION_MAP__EXTENSIONS:
					return ((InternalEList)getExtensions()).basicRemove(otherEnd, msgs);
				default:
					return eDynamicInverseRemove(otherEnd, featureID, baseClass, msgs);
			}
		}
		return eBasicSetContainer(null, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(EStructuralFeature eFeature, boolean resolve) {
		switch (eDerivedStructuralFeatureID(eFeature)) {
			case ExtensionmodelPackage.EXTENSION_MAP__NAMESPACE:
				return getNamespace();
			case ExtensionmodelPackage.EXTENSION_MAP__EXTENSIONS:
				return getExtensions();
		}
		return eDynamicGet(eFeature, resolve);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(EStructuralFeature eFeature, Object newValue) {
		switch (eDerivedStructuralFeatureID(eFeature)) {
			case ExtensionmodelPackage.EXTENSION_MAP__NAMESPACE:
				setNamespace((String)newValue);
				return;
			case ExtensionmodelPackage.EXTENSION_MAP__EXTENSIONS:
				getExtensions().clear();
				getExtensions().addAll((Collection)newValue);
				return;
		}
		eDynamicSet(eFeature, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(EStructuralFeature eFeature) {
		switch (eDerivedStructuralFeatureID(eFeature)) {
			case ExtensionmodelPackage.EXTENSION_MAP__NAMESPACE:
				setNamespace(NAMESPACE_EDEFAULT);
				return;
			case ExtensionmodelPackage.EXTENSION_MAP__EXTENSIONS:
				getExtensions().clear();
				return;
		}
		eDynamicUnset(eFeature);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(EStructuralFeature eFeature) {
		switch (eDerivedStructuralFeatureID(eFeature)) {
			case ExtensionmodelPackage.EXTENSION_MAP__NAMESPACE:
				return NAMESPACE_EDEFAULT == null ? namespace != null : !NAMESPACE_EDEFAULT.equals(namespace);
			case ExtensionmodelPackage.EXTENSION_MAP__EXTENSIONS:
				return extensions != null && !extensions.isEmpty();
		}
		return eDynamicIsSet(eFeature);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (namespace: ");
		result.append(namespace);
		result.append(')');
		return result.toString();
	}

	
	
	/**
	 * This is the Map entrySet. 
	 * @param <K> 
	 * @param <V> 
	 */
	
	public class EntrySet<K,V> extends java.util.AbstractSet<Map.Entry<K,V>> {
		/**
		 * ESet constructor comment.
		 */
		protected EntrySet() {
			super();
		}

		/**
		 * @see java.util.AbstractCollection#iterator()
		 */
		@Override
		public java.util.Iterator<Map.Entry<K,V>> iterator () {
			return new EIterator<Map.Entry<K,V>> () {

				@Override
				protected Map.Entry<K,V> next(Extension extension) {
					return new Entry (extension.getExtendedObject(), extension.getExtensionObject());
				}				
			};			
		}

		/**
		 * @see java.util.AbstractCollection#size()
		 */
		@Override
		public int size() {
			int n=0;
			for (Iterator<?> i=iterator(); i.hasNext(); ) {
				i.next();
				n++;
			}
			return n;
		}
	}

	/**
	 * This is the Map entrySet.
	 */
	public class KeySet extends java.util.AbstractSet<EObject> {

		/**
		 * ESet constructor comment.
		 */
		protected KeySet() {
			super();
		}

		
		/**
		 * @see java.util.AbstractCollection#iterator()
		 */
		@Override
		public java.util.Iterator<EObject> iterator() {
			return new EIterator<EObject>() {
				@Override
				protected EObject next (Extension extension) {
					return extension.getExtendedObject();
				}				
			};
		}

		/**
		 * @see java.util.AbstractCollection#size()
		 */
		@Override
		public int size() {
			int n=0;
			for (Iterator<?> i=iterator(); i.hasNext(); ) {
				i.next();
				n++;
			}
			return n;
		}
	}
	
	
	/**
	 * This is the Map entrySet.  
	 */
	
	public class Values extends AbstractCollection<EObject> {
		/**
		 * ESet constructor comment.
		 */
		protected Values() {
			super();
		}

		/**
		 * @see java.util.AbstractCollection#iterator()
		 */
		@Override
		public java.util.Iterator<EObject> iterator() {
			
			return new EIterator<EObject>() {
				@Override
				protected EObject next (Extension extension) {
					return extension.getExtensionObject() ;
				}				
			};
			
		}

		/**
		 * @see java.util.AbstractCollection#size()
		 */
		@Override
		public int size() {
			int n=0;
			for (Iterator<?> i=iterator(); i.hasNext(); ) {
				i.next();
				n++;
			}
			return n;
		}
	}
	
	/**
	 * This is the map entry iterator.
	 * @param <T> 
	 */
	public abstract class EIterator<T> implements java.util.Iterator<T> {
		Iterator<Extension> fieldListIterator;
		/**
		 * EIterator constructor comment.
		 */
		public EIterator() {
			super();
			fieldListIterator = getExtensions().iterator();
		}
		/**
		 * Returns <tt>true</tt> if the iteration has more elements. (In other
		 * words, returns <tt>true</tt> if <tt>next</tt> would return an element
		 * rather than throwing an exception.)
		 *
		 * @return <tt>true</tt> if the iterator has more elements.
		 */
		public boolean hasNext() {
			return fieldListIterator.hasNext();
		}
		/**
		 * Returns the next element in the iteration.
		 * @return the next element in the iteration.
		 * @exception NoSuchElementException iteration has no more elements.
		 */
		public T next() {
			Extension object = fieldListIterator.next();
			if (object == null) {
				return null;
			}
			return next (object);
		}
		
		protected abstract T next (Extension extension) ;
		
		/**
		 * 
		 * Removes from the underlying collection the last element returned by the
		 * iterator (optional operation).  This method can be called only once per
		 * call to <tt>next</tt>.  The behavior of an iterator is unspecified if
		 * the underlying collection is modified while the iteration is in
		 * progress in any way other than by calling this method.
		 *
		 * @exception UnsupportedOperationException if the <tt>remove</tt>
		 *        operation is not supported by this Iterator.
		 
		 * @exception IllegalStateException if the <tt>next</tt> method has not
		 *        yet been called, or the <tt>remove</tt> method has already
		 *        been called after the last call to the <tt>next</tt>
		 *        method.
		 */
		public void remove() {
			fieldListIterator.remove();
		}

	}
	
	
	/**
	 * Map entry.
	 * @param <K> 
	 * @param <V> 
	 */
	public class Entry<K,V> implements Map.Entry<K,V> {
		K key;
		V value;

		/**
		 * @param aKey
		 * @param aValue
		 */
		public Entry (K aKey, V aValue) {
			this.key = aKey;
			this.value = aValue;
		}

		/**
		 * @see java.util.Map.Entry#getKey()
		 */
		public K getKey() {
			return key;
		}

		/**
		 * @see java.util.Map.Entry#getValue()
		 */
		public V getValue() {
			return value;
		}

		/**
		 * @see java.util.Map.Entry#setValue(java.lang.Object)
		 */
		public V setValue(V aValue) {
			V oldValue = this.value;
			this.value = aValue;
			return oldValue;
		}

		/**
		 * @see java.lang.Object#equals(java.lang.Object)
		 */
		@Override
		public boolean equals(Object o) {
			if (!(o instanceof Map.Entry)) {
				return false;
			}
			
			Map.Entry<?,?> e = (Map.Entry<?,?>) o;
			return (key == null ? e.getKey() == null : key.equals(e.getKey())) && (value == null ? e.getValue() == null : value.equals(e.getValue()));
		}

		/**
		 * @see java.lang.Object#hashCode()
		 */
		@Override
		public int hashCode() {
			return key == null ? 0 : key.hashCode();
		}

		/**
		 * @see java.lang.Object#toString()
		 */
		@SuppressWarnings("nls")
		@Override		
		public String toString() {
			return key + "=" + value;
		}
	}

	/**
	 * @see java.util.Map#size()
	 */
	public int size() {
		return getExtensions().size();
	}

	/** (non-Javadoc)
	 * @see java.util.Map#isEmpty()
	 */
	public boolean isEmpty() {
		return getExtensions().isEmpty();
	}

	/**
	 * @see java.util.Map#containsKey(java.lang.Object)
	 */
	public boolean containsKey(Object extendedObject) {
		
		if ( extendedObject != null ) {
			for (Extension extension : getExtensions()) {
				if(extension.getExtendedObject().equals(extendedObject)){
					return true;					
				}
			}
		}
		return false;
	}

	/**
	 * @see java.util.Map#containsValue(java.lang.Object)
	 */
	public boolean containsValue (Object extensionObject) {
		
		if (extensionObject != null) {
			for (Extension extension : getExtensions()) {
				if (extension.getExtensionObject().equals(extensionObject)){
					return true;					
				}
			}
		}
		return false;
	}

	/**
	 * @see java.util.Map#get(java.lang.Object)
	 * @generated NOT
	 */
	public EObject get(Object extendedObject) {
		EObject extension = null;
		
		extension = getExtensionObject((EObject)extendedObject);
		if (extension!=null) {
			return ((Extension)extension).getExtensionObject();
		}
		return null;
	}

	/**
	 * @param extendedObject 
	 * @param extensionObject 
	 * @return the previous object
	 * @see java.util.Map#put(java.lang.Object, java.lang.Object)
	 * @generated NOT
	 */
	public EObject put(EObject extendedObject, EObject extensionObject) {
		
		EObject originalObject = null;
		
		if(extendedObject != null && extensionObject!= null){
						
			Extension extension = getExtensionObject( extendedObject );
			
			if(extension!= null)
				originalObject = extension.getExtensionObject();	
			else {
				extension = ExtensionmodelFactory.eINSTANCE.createExtension();
				getExtensions().add(extension);
			}

			extension.setExtendedObject(extendedObject);
			extension.setExtensionObject(extensionObject);
						
			ExtensionmodelAdapterFactory adapterFactory = new ExtensionmodelAdapterFactory();
			
			ExtendedObjectAdapter extAdptr = (ExtendedObjectAdapter) adapterFactory.createExtendedObjectAdapter();
			
			extAdptr.setExtension(extension);
			extAdptr.setNamespace(getNamespace());
			
			adaptEObject(extendedObject,extAdptr);

			adapterFactory.adapt(extension,ExtensionAdapterImpl.class);
			
			if(userAdapter == null)
				initializeAdapter();
			else 				
				adaptEObject(extendedObject,userAdapter);
			
			if (eNotificationRequired())
				eNotify(new ExtensionModelNotificationImpl(this, Notification.ADD, ExtensionModelNotification.EXTENSION_MAP_PUT, extendedObject, originalObject));

			return originalObject;
							
		}
		
		return null;
	}

	/**
	 * @see java.util.Map#remove(java.lang.Object)
	 */
	public EObject remove (Object extendedObject) {
		if (extendedObject == null) {
			return null;
		}
		Extension extensionObject = getExtensionObject((EObject)extendedObject);
		if(getExtensions().contains(extensionObject)){
			Object oldExtension = extensionObject.getExtensionObject();
			getExtensions().remove(extensionObject);
			if (eNotificationRequired())
				eNotify(new ExtensionModelNotificationImpl(this, Notification.REMOVE, ExtensionModelNotification.EXTENSION_MAP_REMOVE, extendedObject, oldExtension));
		}
		
		// Remove adapter if one exists
		removeAdapters((EObject) extendedObject);
			
		if(extensionObject != null) {
			return extensionObject.getExtensionObject();
		}
		
		return null;
	}

	/**
	 * @see java.util.Map#putAll(java.util.Map)
	 */
	public void putAll(Map<? extends EObject, ? extends EObject> extendedObjectMap) {

		Map<EObject,EObject> originalMap = null;
		if (eNotificationRequired()){
			originalMap = buildMap();
		}
		
		if(extendedObjectMap != null && !extendedObjectMap.isEmpty()) {
			for (Map.Entry<? extends EObject, ? extends EObject> entry : extendedObjectMap.entrySet()) {
				put(entry.getKey(),entry.getValue());			
			}
		}
		
		if (eNotificationRequired())
			eNotify(new ExtensionModelNotificationImpl(this, Notification.ADD_MANY, ExtensionModelNotification.EXTENSION_MAP_PUTALL, originalMap, null));
		
	}

	/**
	 * @see java.util.Map#clear()
	 */
	public void clear() {
		Map<EObject,EObject> originalMap = null;
		if (eNotificationRequired() && !getExtensions().isEmpty()){
			originalMap = buildMap();
		}

		getExtensions().clear();
		
		if (originalMap != null){
			int et = Notification.REMOVE_MANY;
			if(originalMap.size() == 1)
				et = Notification.REMOVE;
			
			eNotify(new ExtensionModelNotificationImpl(this, et, ExtensionModelNotification.EXTENSION_MAP_CLEAR, originalMap, null));
		}
	}

	/**
	 * @see java.util.Map#keySet()
	 */
	public Set<EObject> keySet() {
		return new KeySet ();
	}

	
	/**
	 * @see java.util.Map#values()
	 */
	public Collection<EObject> values() {
		return new Values ();
	}


	/**
	 * @see java.util.Map#entrySet()
	 */
	public Set<java.util.Map.Entry<EObject, EObject>> entrySet() {
		return new EntrySet<EObject,EObject>();
	}

	
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @customized
	 */
	private Extension getExtensionObject (EObject extendedObject) {
		
		Extension extension = null;

		if (extendedObject!=null) {
		
			// First check if the is an adapted associated with this object.
			// If there is, the adapter points to the Extension object.  Return this
			// object.
			for(Adapter element : extendedObject.eAdapters()) {
				if(element instanceof ExtendedObjectAdapter && ((ExtendedObjectAdapter)element).getNamespace().equals(getNamespace())){
					extension = ((ExtendedObjectAdapter)element).getExtension();
					break;
				}
			}
					
			// Was the extension found though the adapter?  Not if it's null.
			// There is no adapter associated with this bject so we must search the
			// Extension list.  Once the Extension is found, associate an adapter with this
			// object to improve performance in future queries.
			if( extension == null){
									
				for( Extension ext : getExtensions()) {					
					if (ext.getExtendedObject() != null && ext.getExtendedObject().equals(extendedObject)){
						extension = ext;
						
						ExtensionmodelAdapterFactory adapterFactory = new ExtensionmodelAdapterFactory();
				
						ExtendedObjectAdapter extAdptr = (ExtendedObjectAdapter) adapterFactory.createExtendedObjectAdapter();
				
						extAdptr.setExtension(extension);
						extAdptr.setNamespace(getNamespace());
						
						ExtensionmodelFactory.eINSTANCE.adaptEObject(extendedObject,extAdptr);
						
						adapterFactory.adapt(extension,ExtensionAdapterImpl.class);
						
						break;
					}
					 
				}
			}
		}
		
		return extension;
	}
	
	/**
	 * @return ExtendedObjectUserAdapter
	 * @customized
	 */
	public ExtendedObjectUserAdapter getUserAdapter() {
		return userAdapter;
	}
	
	/**
	  * Method adaptEObject.
	  * This method associates an adapter to a model object.
	  * @param target - object to which the adaptor is to be associated
	  * @param adapter - adapter to asociate to target
	  * @customized
	  */
	 private void adaptEObject(EObject target, Adapter adapter) {
		
		if(target != null  && adapter != null){
			for (Adapter next : target.eAdapters()) {			   
			   if ((adapter instanceof ExtendedObjectUserAdapter && next instanceof ExtendedObjectUserAdapter && ((ExtendedObjectUserAdapter)next).getNamespace().equals(getNamespace()))||
			       (adapter instanceof ExtendedObjectAdapter && next instanceof ExtendedObjectAdapter && ((ExtendedObjectAdapter)next).getNamespace().equals(getNamespace())))
				 return;
			 }
			   
			 target.eAdapters().add(adapter);
		}
	   
	 }

	 /**
	  * @customized
	  */
	 private void removeAdapters(EObject target) {
		
		if(target != null){
			EList<Adapter> removeAdapterList = new BasicEList<Adapter>();
			for (Adapter adapter : target.eAdapters()) {				
				if ((adapter instanceof ExtendedObjectUserAdapter && ((ExtendedObjectUserAdapter)adapter).getNamespace().equals(getNamespace()))||
					(adapter instanceof ExtendedObjectAdapter && ((ExtendedObjectAdapter)adapter).getNamespace().equals(getNamespace())))
					removeAdapterList.add(adapter);	
			}
		   	for(Adapter next : removeAdapterList) {		   	
				target.eAdapters().remove(next); 
			}
		}
	 }

	 private Map<EObject,EObject> buildMap(){
	 	
	 	boolean buildMap = false;
	 	for (Adapter element : eAdapters()) {
	 		if(!(element instanceof ExtendedObjectAdapterImpl) && 
	 				!(element instanceof ExtendedObjectUserAdapterImpl) && 
					!(element instanceof ExtensionAdapterImpl) && 
					!(element instanceof ExtensionMapAdapterImpl)){
	 			buildMap = true;
	 			break;
	 		}
	 	}
	    
	 	if(!buildMap)
	 		return null;
	 	
		Map<EObject,EObject> map = new HashMap<EObject,EObject>();
		for (Extension element : getExtensions()) {
			map.put(element.getExtendedObject(), element.getExtensionObject());				
		}		
		return map;
	 }

	

	

} //ExtensionMapImpl
