//------------------------------------------------------------------------------
// 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():");
					System.out.println("  object: " + this);
					System.out.println("  feature: " + feature);
					System.out.println("  proxy: " + oldValue);
					System.out.println("  resolved: " + newValue);
				}
			} 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;
	}
}