//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.uma.ecore.impl;

import java.io.File;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.CommonPlugin;
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.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.Resource.Internal;
import org.eclipse.emf.ecore.sdo.impl.EDataObjectImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.epf.uma.ecore.IModelObject;
import org.eclipse.epf.uma.ecore.IProxyResolutionListener;
import org.eclipse.epf.uma.ecore.IUmaResourceSet;
import org.eclipse.epf.uma.ecore.ResolveException;
import org.eclipse.epf.uma.ecore.util.DefaultValueManager;
import org.eclipse.epf.uma.ecore.util.OppositeFeature;
import org.eclipse.epf.uma.ecore.util.OppositeFeatureResolvingEList;

/**
 * The base class for all UMA model objects.
 * <p>
 * By default, EMF stores model objects related via a containment relationship
 * in a single XMI file. This class extends the default EMF persistence behavior
 * by providing a mechanism for the containing and contained objects to be
 * stored in separate XMI files. Contained objects are lazy loaded, when
 * required, similar to the proxy object behavior of EMF's standard resource
 * implementation.
 * 
 * @author Phong Nguyen Le
 * @since 1.0
 */
public class MultiResourceEObject extends EDataObjectImpl implements
		IModelObject {

	private static final long serialVersionUID = 3258126947153097273L;
	
	private static final boolean DEBUG = false;
	
	private static final DefaultValueManager defaultValueManager = DefaultValueManager.INSTANCE;
	
	/**
	 * Sets the default value for a feature.
	 * <p>
	 * Note: This method is designed for migration use only. Do not call this
	 * method to override the default value of a feature since it will slow down
	 * the loading of a method library.
	 * 
	 * @param feature
	 *            a feature
	 * @param defaultValue
	 *            the default value for the feature
	 */
	public static final void setDefaultValue(EStructuralFeature feature,
			Object defaultValue) {		
		setDefaultValue(feature.getEContainingClass(), feature, defaultValue);
	}
	
	public static final synchronized void setDefaultValue(EClass type, EStructuralFeature feature, Object defaultValue) {
		defaultValueManager.setDefaultValue(type, feature, defaultValue);
	}
	
	/**
	 * Removes the default value for a feature.
	 * <p>
	 * Note: This method is designed for migration use only. Do not call this
	 * method to override the default value of a feature since it will slow down
	 * the loading of a method library.
	 * 
	 * @param feature
	 *            a feature
	 */
	public static final void removeDefaultValue(EStructuralFeature feature) {
		defaultValueManager.removeDefaultValue(feature);
	}
	
	public static final void removeDefaultValue(EStructuralFeature feature, EClass type) {
		defaultValueManager.removeDefaultValue(feature, type);
	}
	
	/**
	 * A map of entries of OppositeFeature / OppositeFeature's value
	 */
	private Map oppositeFeatureMap;

	private boolean hasOppositeFeature = true;

	private Boolean notifyOpposite = null;

	private boolean valid = true;

	/**
	 * Checks the validity of this object.
	 * 
	 * @return <code>true</code> if this object is valid
	 */
	public boolean isValid() {
		return valid;
	}

	public void oppositeAdd(OppositeFeature oppositeFeature, Object object) {
		List list = (List) getOppositeFeatureMap().get(oppositeFeature);
		if (list == null) {
			list = new OppositeFeatureResolvingEList(this, oppositeFeature);
			getOppositeFeatureMap().put(oppositeFeature, list);
		}
		if (!list.contains(object)) {
			list.add(object);
		}
	}

	public void oppositeRemove(OppositeFeature oppositeFeature, Object object) {
		List list = (List) getOppositeFeatureMap().get(oppositeFeature);
		if (list == null) {
			list = new OppositeFeatureResolvingEList(this, oppositeFeature);
			getOppositeFeatureMap().put(oppositeFeature, list);
		}
		list.remove(object);
	}

	/**
	 * Resolves the given proxy object.
	 * 
	 * @param object
	 *            a proxy object to resolve
	 * @return the resolved object
	 */
	public Object resolve(Object object) {
		if (object instanceof InternalEObject
				&& ((InternalEObject) object).eIsProxy()) {
			return eResolveProxy((InternalEObject) object);
		}
		return object;
	}

	private void replace(EStructuralFeature feature, Object oldValue,
			InternalEObject newValue) {
		if (newValue != null && !newValue.eIsProxy() && newValue != oldValue) {
			boolean notify = eDeliver();
			try {
				eSetDeliver(false);
				EcoreUtil.replace(this, feature, oldValue, newValue);
			} catch (Exception e) {
				if (DEBUG) {
					CommonPlugin.INSTANCE.log(e);
					e.printStackTrace();
					System.out.println("MultiResourceEObject.replace():"); //$NON-NLS-1$
					System.out.println("  object: " + this); //$NON-NLS-1$
					System.out.println("  feature: " + feature); //$NON-NLS-1$
					System.out.println("  proxy: " + oldValue); //$NON-NLS-1$
					System.out.println("  resolved: " + newValue); //$NON-NLS-1$
				}
			} finally {
				eSetDeliver(notify);
			}
		}

	}

	/**
	 * @see org.eclipse.emf.common.notify.impl.BasicNotifierImpl#eNotify(org.eclipse.emf.common.notify.Notification)
	 */
	public void eNotify(Notification msg) {
		/*
		 * if(!OppositeFeature.isDeliverOnResolve() && msg.getEventType() ==
		 * Notification.RESOLVE) { return; }
		 */

		if (msg.getEventType() == Notification.RESOLVE) {
			return;
		}
		
		Object f = msg.getFeature();
		if (f instanceof EStructuralFeature) {
			EStructuralFeature feature = (EStructuralFeature) f;
			OppositeFeature oppositeFeature = OppositeFeature
					.getOppositeFeature(feature);
			if (oppositeFeature != null) {
				MultiResourceEObject oldOtherEnd;
				MultiResourceEObject otherEnd;
				if (oppositeFeature.isMany()) {
					switch (msg.getEventType()) {
					case Notification.SET:
						oldOtherEnd = (MultiResourceEObject) msg.getOldValue();
						if (oppositeFeature.resolveOwner()) {
							oldOtherEnd = (MultiResourceEObject) resolve(oldOtherEnd);
						}
						if (oldOtherEnd != null) {
							oldOtherEnd.oppositeRemove(oppositeFeature, msg
									.getNotifier());
						}
					case Notification.ADD:
						otherEnd = (MultiResourceEObject) msg.getNewValue();
						if (oppositeFeature.resolveOwner()) {
							otherEnd = (MultiResourceEObject) resolve(otherEnd);
							replace(feature, msg.getNewValue(), otherEnd);
						}
						if (otherEnd != null) {
							otherEnd.oppositeAdd(oppositeFeature, msg
									.getNotifier());
						}
						break;
					case Notification.ADD_MANY:
						for (Iterator iter = ((Collection) msg.getNewValue())
								.iterator(); iter.hasNext();) {
							Object obj = iter.next();
							otherEnd = (MultiResourceEObject) obj;
							if (oppositeFeature.resolveOwner()) {
								otherEnd = (MultiResourceEObject) resolve(otherEnd);
								replace(feature, obj, otherEnd);
							}
							otherEnd.oppositeAdd(oppositeFeature, msg
									.getNotifier());
						}
						break;
					case Notification.REMOVE:
						otherEnd = (MultiResourceEObject) msg.getOldValue();
						if (oppositeFeature.resolveOwner()) {
							otherEnd = (MultiResourceEObject) resolve(otherEnd);
						}
						if (otherEnd != null)
							otherEnd.oppositeRemove(oppositeFeature, msg
									.getNotifier());
						break;
					case Notification.REMOVE_MANY:
						for (Iterator iter = ((Collection) msg.getOldValue())
								.iterator(); iter.hasNext();) {
							otherEnd = (MultiResourceEObject) iter.next();
							if (oppositeFeature.resolveOwner()) {
								otherEnd = (MultiResourceEObject) resolve(otherEnd);
							}
							otherEnd.oppositeRemove(oppositeFeature, msg
									.getNotifier());
						}
						break;
					}
				} else {
					switch (msg.getEventType()) {
					case Notification.ADD_MANY:
						for (Iterator iter = ((Collection) msg.getNewValue())
								.iterator(); iter.hasNext();) {
							Object obj = iter.next();
							otherEnd = (MultiResourceEObject) obj;
							if (oppositeFeature.resolveOwner()) {
								otherEnd = (MultiResourceEObject) resolve(otherEnd);
								replace(feature, obj, otherEnd);
							}
							if (otherEnd != null) {
								EObject oldValue = (EObject) otherEnd
										.getOppositeFeatureMap().get(
												oppositeFeature);
								if (oldValue != null) {
									// remove otherEnd from target feature of
									// oldValue
									((Collection) oldValue
											.eGet((EStructuralFeature) f))
											.remove(otherEnd);
								}
								otherEnd.getOppositeFeatureMap().put(
										oppositeFeature, msg.getNotifier());
							}
						}
						break;
					case Notification.REMOVE_MANY:
						for (Iterator iter = ((Collection) msg.getOldValue())
								.iterator(); iter.hasNext();) {
							otherEnd = (MultiResourceEObject) iter.next();
							if (oppositeFeature.resolveOwner()) {
								otherEnd = (MultiResourceEObject) resolve(otherEnd);
							}
							otherEnd.getOppositeFeatureMap().put(
									oppositeFeature, null);
						}
						break;
					case Notification.ADD:
						otherEnd = (MultiResourceEObject) msg.getNewValue();
						if (oppositeFeature.resolveOwner()) {
							otherEnd = (MultiResourceEObject) resolve(otherEnd);
							replace(feature, msg.getNewValue(), otherEnd);
						}
						if (otherEnd != null) {
							EObject oldValue = (EObject) otherEnd
									.getOppositeFeatureMap().get(
											oppositeFeature);
							if (oldValue != null) {
								// remove otherEnd from target feature of
								// oldValue
								((Collection) oldValue
										.eGet((EStructuralFeature) f))
										.remove(otherEnd);
							}
							otherEnd.getOppositeFeatureMap().put(
									oppositeFeature, msg.getNotifier());
						}
						break;
					case Notification.SET:
						otherEnd = (MultiResourceEObject) msg.getNewValue();
						if (oppositeFeature.resolveOwner()) {
							otherEnd = (MultiResourceEObject) resolve(otherEnd);
							replace(feature, msg.getNewValue(), otherEnd);
						}
						if (otherEnd != null) {
							EObject oldValue = (EObject) otherEnd
									.getOppositeFeatureMap().get(
											oppositeFeature);
							if (oldValue != null) {
								// set the target feature of oldValue to null
								oldValue.eSet((EStructuralFeature) f, null);
							}
							otherEnd.getOppositeFeatureMap().put(
									oppositeFeature, msg.getNotifier());
						}
						else {
							EStructuralFeature targetFeature = (EStructuralFeature) f;
							if(!targetFeature.isMany()) {
								oldOtherEnd = (MultiResourceEObject) msg.getOldValue();
								if(oldOtherEnd != null) {
									oldOtherEnd.getOppositeFeatureMap().put(oppositeFeature, null);
								}
							}
						}
						break;
					case Notification.REMOVE:
						// case Notification.UNSET:
						otherEnd = (MultiResourceEObject) msg.getOldValue();
						if (oppositeFeature.resolveOwner()) {
							otherEnd = (MultiResourceEObject) resolve(otherEnd);
						}
						if (otherEnd != null)
							otherEnd.getOppositeFeatureMap().put(
									oppositeFeature, null);
						break;

					}
				}
			}
		}

		super.eNotify(msg);
	}

	/**
	 * @see org.eclipse.emf.common.notify.impl.BasicNotifierImpl#eNotificationRequired()
	 */
	public boolean eNotificationRequired() {
		if (!eDeliver())
			return false;

		Resource resource = eResource();
		if (resource != null && !resource.eDeliver())
			return false;

		if (notifyOpposite == null) {
			if (OppositeFeature.featureOppositeFeatureMap.isEmpty()) {
				notifyOpposite = Boolean.FALSE;
			} else {
				Collection features = OppositeFeature.featureOppositeFeatureMap
						.keySet();
				for (Iterator iter = eClass().getEAllReferences().iterator(); iter
						.hasNext();) {
					if (features.contains(iter.next())) {
						notifyOpposite = Boolean.TRUE;
						break;
					}
				}
				if (notifyOpposite == null) {
					notifyOpposite = Boolean.FALSE;
				}
			}
		}
		if (notifyOpposite.booleanValue())
			return true;
		return super.eNotificationRequired();
	}

	/*
	 * private void removeChildResources() { List children = eContents(); int
	 * size = children.size(); for (int i = 0; i < size; i++) {
	 * MultiResourceEObject child = (MultiResourceEObject) children.get(i);
	 * Resource resource = child.eResource(); if (resource != null && resource !=
	 * eResource()) { child.removeChildResources(); } ((InternalEList)
	 * resource.getContents()).basicRemove(this, null);
	 * child.eProperties().setEResource(null); } }
	*/

	/**
	 * @see org.eclipse.emf.ecore.InternalEObject#eBasicSetContainer(org.eclipse.emf.ecore.InternalEObject,
	 *      int, org.eclipse.emf.common.notify.NotificationChain)
	 */
	public NotificationChain eBasicSetContainer(InternalEObject newContainer,
			int newContainerFeatureID, NotificationChain msgs) {
		Resource.Internal oldResource = this.eDirectResource();
		Resource.Internal newResource = newContainer == null ? null
				: newContainer.eInternalResource();
		// if (oldResource != newResource && oldResource != null) {
		// removeChildResources();
		// }

		int oldIndex = -1;
		int oldSize = -1;
		if (oldResource != null) {
			oldIndex = oldResource.getContents().indexOf(this);
			oldSize = oldResource.getContents().size();
		}

		NotificationChain messages = super.eBasicSetContainer(newContainer,
				newContainerFeatureID, msgs);
		if (oldResource != newResource && oldResource != null) {
			// remove any newly added ModificationTrackingAdapters from this
			// object's adapter list
			//
			if (newResource != null)
				newResource.detached(this);

			// Override the default semantic: MultiResourceEObject is allowed to
			// be owned by both container and resource.
			// Add this object back to the old resource.
			//
			BasicEList contents = ((BasicEList) oldResource.getContents());
			if (oldSize != contents.size()) {
				// this object has been removed from the resource's contents
				// add it back
				//
				if (contents.isEmpty()) {
					// this will flag resource as loaded
					//
					contents.clear();
					contents.setData(1, new Object[] { this });
				} else {
					Object[] data = contents.toArray();
					Object[] newData = new Object[data.length + 1];
					if (oldIndex > 0) {
						System.arraycopy(data, 0, newData, 0, oldIndex);
					}
					newData[oldIndex] = this;
					if (oldIndex < data.length) {
						System.arraycopy(data, oldIndex, newData, oldIndex + 1,
								data.length - oldIndex);
					}
					contents.setData(newData.length, newData);
				}
			}
			eSetResource(oldResource);
			// don't have to re-attach this object to oldResource since it was
			// not dettached in super method
			//
			// oldResource.attached(this);

			// if(newResource != null) newResource.attached(this);
		}
		return messages;
	}

	/**
	 * Sets the container and container feature ID for this object only if it is
	 * not contained by any container.
	 * 
	 * @see org.eclipse.emf.ecore.impl.BasicEObjectImpl#eBasicSetContainer(org.eclipse.emf.ecore.InternalEObject,
	 *      int)
	 */
	public void eSetContainer(InternalEObject newContainer,
			int newContainerFeatureID) {
		EObject container = eInternalContainer();
		if (container != null && !container.eIsProxy())
			return;
		super.eBasicSetContainer(newContainer, newContainerFeatureID);
	}

	/**
	 * @see org.eclipse.emf.ecore.impl.BasicEObjectImpl#eBasicSetContainer(org.eclipse.emf.ecore.InternalEObject,
	 *      int)
	 */
	public void eBasicSetContainer(InternalEObject newContainer,
			int newContainerFeatureID) {
		super.eBasicSetContainer(newContainer, newContainerFeatureID);
	}

	/**
	 * Sets the containing resource for this object.
	 * 
	 * @param res
	 *            a resource
	 */
	public void eSetResource(Resource.Internal res) {
		eProperties().setEResource(res);
	}

	/**
	 * @see org.eclipse.emf.ecore.impl.BasicEObjectImpl#eDirectResource()
	 */
	public Internal eDirectResource() {
		return super.eDirectResource();
	}

	/**
	 * Returns the resolved object represented by proxy. Proxy chains are
	 * followed. If resourceSet is null, the global package registry is
	 * consulted to obtain a package registered against the proxy URI, less its
	 * fragment, in the same manner as the default resource set implementation's
	 * fallback behaviour.
	 * 
	 * @param proxy
	 *            the proxy to be resolved.
	 * @param resourceSet
	 *            the resource set in which to resolve.
	 * @return the resolved object, or the proxy if unable to resolve.
	 * @see org.eclipse.emf.ecore.util.EcoreUtil#resolve(org.eclipse.emf.ecore.EObject,
	 *      org.eclipse.emf.ecore.resource.ResourceSet)
	 */
	private EObject resolveProxy(EObject proxy) {
		ResourceSet resourceSet = eResource() != null ? eResource()
				.getResourceSet() : null;

		URI proxyURI = ((InternalEObject) proxy).eProxyURI();
		if (proxyURI != null) {
			try {
				EObject resolvedObject = null;

				if (resourceSet != null) {
					if (resourceSet instanceof IUmaResourceSet) {
						resolvedObject = ((IUmaResourceSet) resourceSet)
								.getEObject(this, proxyURI, true);
					} else {
						resolvedObject = resourceSet.getEObject(proxyURI, true);
					}
				} else {
					EPackage ePackage = EPackage.Registry.INSTANCE
							.getEPackage(proxyURI.trimFragment().toString());
					if (ePackage != null) {
						Resource resource = ePackage.eResource();
						if (resource != null) {
							resolvedObject = resource.getEObject(proxyURI
									.fragment().toString());
						}
					}
				}

				if (resolvedObject != null) {
					if(resolvedObject != proxy) {
//						return resolveProxy(resolvedObject);
						return resolvedObject;
					}
				} else {
					if (resourceSet instanceof IProxyResolutionListener) {
						((IProxyResolutionListener) resourceSet)
								.notifyException(new ResolveException(proxy,
										(String) null, this));
					}
				}
			} catch (RuntimeException exception) {
				if (resourceSet instanceof IProxyResolutionListener) {
					((IProxyResolutionListener) resourceSet)
							.notifyException(new ResolveException(proxy,
									exception, this));
				}
			}
		}
		return proxy;
	}

	/**
	 * @see org.eclipse.emf.ecore.InternalEObject#eResolveProxy(org.eclipse.emf.ecore.InternalEObject)
	 */
	public EObject eResolveProxy(InternalEObject proxy) {
		EObject container = proxy.eContainer();
		int featureID = proxy.eContainerFeatureID();
		EObject result = null;

		result = resolveProxy(proxy);

		if (result != null && result instanceof MultiResourceEObject) {
			if (proxy.eIsProxy() && result == proxy) {
				// proxy could not be resolved
				//
				((MultiResourceEObject) result).valid = false;
			} else {
				((MultiResourceEObject) result).valid = true;

				if (container != null) {
					((MultiResourceEObject) result).eSetContainer(
							(InternalEObject) container, featureID);
				}

				// merge the opposite feature map
				//
				if (result != proxy) {
					if(proxy instanceof MultiResourceEObject) {
						MultiResourceEObject myObj = (MultiResourceEObject) proxy;

						if (myObj.oppositeFeatureMap != null
								&& !myObj.oppositeFeatureMap.isEmpty()) {
							Map newMap = ((MultiResourceEObject) result)
							.getOppositeFeatureMap();
							for (Iterator iter = myObj.getOppositeFeatureMap()
									.entrySet().iterator(); iter.hasNext();) {
								Map.Entry entry = (Map.Entry) iter.next();
								if (entry.getValue() != null) {
									OppositeFeature oppositeFeature = (OppositeFeature) entry
									.getKey();
									if (oppositeFeature.isMany()) {
										List values = (List) newMap
										.get(oppositeFeature);
										if (values == null) {
											newMap.put(oppositeFeature, entry
													.getValue());
										} else {
											values.addAll((Collection) entry
													.getValue());
										}
									} else {
										newMap.put(oppositeFeature, entry
												.getValue());
									}
								}
							}
							myObj.getOppositeFeatureMap().clear();
						}
					}
					
					ResourceSet resourceSet = eResource() != null ? eResource()
							.getResourceSet() : null;
					if (resourceSet instanceof IProxyResolutionListener) {
						((IProxyResolutionListener) resourceSet).proxyResolved(
								proxy, result);
					}
				}
			}

		}

		return result;
	}

	private Map createOppositeFeatureMap() {
		Map map = new HashMap();
		for (Iterator iter = OppositeFeature.classOppositeFeaturesMap
				.entrySet().iterator(); iter.hasNext();) {
			Map.Entry entry = (Map.Entry) iter.next();
			Class cls = (Class) entry.getKey();
			if (cls.isInstance(this)) {
				for (Iterator iterator = ((Collection) entry.getValue())
						.iterator(); iterator.hasNext();) {
					map.put(iterator.next(), null);
				}
			}
		}
		if (map.isEmpty()) {
			hasOppositeFeature = false;
			return Collections.EMPTY_MAP;
		}
		return map;
	}

	/**
	 * Gets the opposite feature map.
	 * 
	 * @return a map containing the opposite features mapped to their values
	 */
	public Map getOppositeFeatureMap() {
		if (oppositeFeatureMap == null && hasOppositeFeature) {
			oppositeFeatureMap = createOppositeFeatureMap();
		}
		if(oppositeFeatureMap == null) {
			return Collections.EMPTY_MAP;
		}
		return oppositeFeatureMap;
	}

	/**
	 * Gets the opposite feature map.
	 * 
	 * @return a map containing the opposite features mapped to their values or
	 *         <code>null</code> if this object does not have any opposite
	 *         feature or the map has not been created
	 */
	public Map basicGetOppositeFeatureMap() {
		return oppositeFeatureMap;
	}

	/**
	 * Gets the value of an opposite feature.
	 * 
	 * @param feature
	 *            an opposite feature
	 * @return the value for the opposite feature
	 */
	public Object getOppositeFeatureValue(OppositeFeature feature) {
		Object value = getOppositeFeatureMap().get(feature);

		// System.out.println("MultiResourceEObject.getOppositeFeatureValue():");
		// System.out.println(" feature: " + feature);
		// System.out.println(" value: " + value);
		// System.out.println(" this: " + this);

		if (feature.isMany()) {
			if (value == null) {
				return Collections.EMPTY_LIST;
			}

			return ((OppositeFeatureResolvingEList) value)
					.getUnmodifiableList();
		} else if (value instanceof EObject
				&& ((EObject) value).eResource() == null) {
			getOppositeFeatureMap().put(feature, null);
			return null;
		}

		if (value instanceof InternalEObject
				&& ((InternalEObject) value).eIsProxy()) {
			EObject resolved = eResolveProxy((InternalEObject) value);
			if (resolved != value) {
				getOppositeFeatureMap().put(feature, resolved);
				value = resolved;
			}
		}
		return value;
	}

	/**
	 * Gets the resource at a given location.
	 * 
	 * @param location
	 *            the resource location
	 * @return a resource in the workspace
	 */
	public static IResource getResourceForLocation(String location) {
		IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
		IPath path = new Path(location);
		IResource resource;
		File file =  new File(location);
		if (file.isFile()) {
			resource = workspaceRoot.getFileForLocation(path);
			if(resource == null) {
				IResource parentResource = getResourceForLocation(file
						.getParent());
				if(parentResource != null) {
					try {
						parentResource.refreshLocal(IResource.DEPTH_ONE, null);
					} catch (CoreException e) {
						CommonPlugin.INSTANCE.log(e);
					}
					resource = workspaceRoot.getFileForLocation(path);
				}
			}
		} else {
			resource = workspaceRoot.getContainerForLocation(path);
		}
		return resource;
	}

//	/* (non-Javadoc)
//	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
//	 */
//	public Object getAdapter(Class adapter) {
//		if(adapter == IResource.class) {
//			Resource resource = eResource();
//			if(resource != null) {
//				return getResourceForLocation(resource.getURI().toFileString());
//			}
//		}
//		return null;
//	}
	
	/**
	 * Removes all opposite features registered with the system.
	 */
	public void removeFromAllOppositeFeatures() {
		// find all features that have opposite features and clear those
		// features. This will remove the references to
		// unloaded object by those opposite features
		//
		for (Iterator iter = eClass().getEAllReferences().iterator(); iter
				.hasNext();) {
			EReference ref = (EReference) iter.next();
			OppositeFeature oppositeFeature = OppositeFeature.getOppositeFeature(ref);
			if(oppositeFeature != null) {
				if(ref.isMany()) {
					List list = (List) eGet(ref, false);					
					if(!list.isEmpty()) {
						if(!oppositeFeature.resolveOwner()) {
							list.clear();
						}
						else if(list instanceof InternalEList) {
							List basicList = ((InternalEList)list).basicList();
							for(int i = basicList.size() - 1; i > -1; i--) {
								EObject e = (EObject) basicList.get(i);
								if(!e.eIsProxy()) {
									list.remove(e);
								}
							}
						}
					}
				}
				else {
					EObject e = (EObject) eGet(ref, false);
					if(e != null && !e.eIsProxy()) {
						eSet(ref, null);
					}
				}
			}
		}

	}

	/**
	 * @see org.eclipse.epf.uma.ecore.IModelObject#getOppositeFeatures()
	 */
	public Collection getOppositeFeatures() {
		return getOppositeFeatureMap().keySet();
	}

	/**
	 * @see org.eclipse.epf.uma.ecore.IModelObject#getDefaultValue(org.eclipse.emf.ecore.EStructuralFeature)
	 */
	public Object getDefaultValue(EStructuralFeature feature) {
		Object value = getFeatureToDefaultValueMap().get(feature);
		if(value == null) {
			value = feature.getDefaultValue();
		}
		return value;
	}
	
	private Map<EStructuralFeature, Object> getFeatureToDefaultValueMap() {
		return defaultValueManager.getFeatureToDefaultValueMap(eClass());
	}
	
	/**
	 * Unregisters a feature whose default value has been overriden.
	 * 
	 * @param feature
	 *            a feature
	 */
	public void removeFeatureWithOverridenDefaultValue(
			EStructuralFeature feature) {
		Map featureToDefaultValueMap = getFeatureToDefaultValueMap();
		if(featureToDefaultValueMap != null) {
			try {
				featureToDefaultValueMap.remove(feature);
			} catch (Exception e) {
				//
			}
		}
	}

	/**
	 * Reassign default values that are defined statically or dynamically for this class
	 */
	protected void reassignDefaultValues() {
		defaultValueManager.assignDefaultValues(this);
	}
	
	protected EStructuralFeature getFeatureWithOverridenDefaultValue(
			int featureID) {
		Map featureToDefaultValueMap = getFeatureToDefaultValueMap();
		if(!featureToDefaultValueMap.isEmpty()) {
			EStructuralFeature feature = eClass().getEStructuralFeature(
					featureID);
			if(feature != null && featureToDefaultValueMap.containsKey(feature)) {
				return feature;
			}
		}
		return null;
	}
	
	protected boolean isFeatureWithOverridenDefaultValueSet(
			EStructuralFeature feature) {
		Object defaultValue = getDefaultValue(feature);
		Object value = eGet(feature, false);
		if(feature.isMany()) {
			return value != null && !((Collection) value).isEmpty()
			&& value != defaultValue;
		} else {
			return defaultValue == null ? value != null : !defaultValue
					.equals(value);
		}
		
//		// Always return true so the feature (with default value overriden)
//		// will be saved regardless that its value is the default value or not.
//		//
//		return true;
	}
}