/*******************************************************************************
 * Copyright (c) 2010, 2011 Oracle. 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:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.jaxb.core.internal.context.java;

import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.common.utility.Filter;
import org.eclipse.jpt.common.utility.internal.CollectionTools;
import org.eclipse.jpt.common.utility.internal.iterables.ChainIterable;
import org.eclipse.jpt.common.utility.internal.iterables.CompositeIterable;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyIterable;
import org.eclipse.jpt.common.utility.internal.iterables.FilteringIterable;
import org.eclipse.jpt.common.utility.internal.iterables.LiveCloneIterable;
import org.eclipse.jpt.common.utility.internal.iterables.SingleElementIterable;
import org.eclipse.jpt.common.utility.internal.iterables.SubIterableWrapper;
import org.eclipse.jpt.common.utility.internal.iterables.TransformationIterable;
import org.eclipse.jpt.jaxb.core.MappingKeys;
import org.eclipse.jpt.jaxb.core.context.JaxbAttributeMapping;
import org.eclipse.jpt.jaxb.core.context.JaxbAttributesContainer;
import org.eclipse.jpt.jaxb.core.context.JaxbClass;
import org.eclipse.jpt.jaxb.core.context.JaxbContainmentMapping;
import org.eclipse.jpt.jaxb.core.context.JaxbContextRoot;
import org.eclipse.jpt.jaxb.core.context.JaxbPackageInfo;
import org.eclipse.jpt.jaxb.core.context.JaxbPersistentAttribute;
import org.eclipse.jpt.jaxb.core.context.JaxbPersistentClass;
import org.eclipse.jpt.jaxb.core.context.XmlAccessOrder;
import org.eclipse.jpt.jaxb.core.context.XmlAccessType;
import org.eclipse.jpt.jaxb.core.context.XmlAdaptable;
import org.eclipse.jpt.jaxb.core.context.XmlJavaTypeAdapter;
import org.eclipse.jpt.jaxb.core.context.XmlSeeAlso;
import org.eclipse.jpt.jaxb.core.internal.validation.DefaultValidationMessages;
import org.eclipse.jpt.jaxb.core.internal.validation.JaxbValidationMessages;
import org.eclipse.jpt.jaxb.core.resource.java.JAXB;
import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceAbstractType;
import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceAnnotatedElement;
import org.eclipse.jpt.jaxb.core.resource.java.JavaResourceType;
import org.eclipse.jpt.jaxb.core.resource.java.XmlAccessorOrderAnnotation;
import org.eclipse.jpt.jaxb.core.resource.java.XmlAccessorTypeAnnotation;
import org.eclipse.jpt.jaxb.core.resource.java.XmlJavaTypeAdapterAnnotation;
import org.eclipse.jpt.jaxb.core.resource.java.XmlSeeAlsoAnnotation;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;

/**
 * To support inherited attributes in the Generic case I have made some assumptions
 * based on the JAXB RIs interpretation of the spec. Any superclass that is
 * marked as @XmlTransient will have a corresponding JaxbAttributesContainer for its JaxbClass.
 * If that XmlTransient class has no access type specified, the access type will be determined
 * by this JaxbPersistentClass's access type. If the XmlTransient class specified an access
 * type it will only be used in the case where this class does not specify an access type.
 * It will be this class's default access type. The spec states that you are not allowed
 * to use other annotations along with XmlTransient, but it appears the reference implementation
 * has made an exception for @XmlAccessorType and @XmlAccessorOrder. This is subject to change
 * pending a discussion with Blaise and the developers of the RI
 *
 */
public class GenericJavaPersistentClass
		extends AbstractJavaPersistentType
		implements JaxbPersistentClass {
	
	protected JaxbClass superClass;
	
	protected XmlAccessType defaultAccessType;
	protected XmlAccessType specifiedAccessType;
	
	protected XmlAccessOrder defaultAccessOrder;
	protected XmlAccessOrder specifiedAccessOrder;
	
	protected final XmlAdaptable xmlAdaptable;
	
	protected XmlSeeAlso xmlSeeAlso;
	
	protected final JaxbAttributesContainer attributesContainer;
	
	protected final Map<JaxbClass, JaxbAttributesContainer> inheritedAttributesContainers = new HashMap<JaxbClass, JaxbAttributesContainer>();
	
	public GenericJavaPersistentClass(JaxbContextRoot parent, JavaResourceType resourceType) {
		super(parent, resourceType);
		this.superClass = this.buildSuperClass();
		this.specifiedAccessType = this.getResourceAccessType();
		this.specifiedAccessOrder = this.getResourceAccessOrder();
		this.defaultAccessType = this.buildDefaultAccessType();
		this.defaultAccessOrder = this.buildDefaultAccessOrder();
		this.xmlAdaptable = this.buildXmlAdaptable();
		initXmlSeeAlso();
		this.attributesContainer = new GenericJavaAttributesContainer(this, buildAttributesContainerOwner(), resourceType);
		this.initializeInheritedAttributes();
	}
	
	
	@Override
	public JavaResourceType getJavaResourceType() {
		return (JavaResourceType) super.getJavaResourceType();
	}
	
	
	// ********** synchronize/update **********
	
	@Override
	public void synchronizeWithResourceModel() {
		super.synchronizeWithResourceModel();
		this.setSpecifiedAccessType_(this.getResourceAccessType());
		this.setSpecifiedAccessOrder_(this.getResourceAccessOrder());
		this.xmlAdaptable.synchronizeWithResourceModel();
		syncXmlSeeAlso();
		this.attributesContainer.synchronizeWithResourceModel();
		this.syncInheritedAttributes();
	}
	
	@Override
	public void update() {
		super.update();
		super.update();
		this.setSuperClass(this.buildSuperClass());
		this.setDefaultAccessType(this.buildDefaultAccessType());
		this.setDefaultAccessOrder(this.buildDefaultAccessOrder());
		this.xmlAdaptable.update();
		updateXmlSeeAlso();
		this.attributesContainer.update();
		this.updateInheritedAttributes();
	}
	
	
	// ********** JaxbType impl **********
	
	public Kind getKind() {
		return Kind.PERSISTENT_CLASS;
	}
	
	@Override
	public Iterable<String> getDirectlyReferencedTypeNames() {
		return new CompositeIterable<String>(
				new SingleElementIterable(getJavaResourceType().getSuperclassQualifiedName()),
				new CompositeIterable<String>(
						new TransformationIterable<JaxbPersistentAttribute, Iterable<String>>(getAttributes()) {
							@Override
							protected Iterable<String> transform(JaxbPersistentAttribute o) {
								return o.getMapping().getDirectlyReferencedTypeNames();
							}
						}),
				getXmlSeeAlsoClasses());
	}
	
	protected Iterable<String> getXmlSeeAlsoClasses() {
		return (this.xmlSeeAlso == null) ?
				EmptyIterable.<String>instance()
				: getXmlSeeAlso().getDirectlyReferencedTypeNames();
	}
	
	
	// ********** super class **********
	
	public JaxbClass getSuperClass() {
		return this.superClass;
	}
	
	protected void setSuperClass(JaxbClass superClass) {
		JaxbClass old = this.superClass;
		this.superClass = superClass;
		this.firePropertyChanged(SUPER_CLASS_PROPERTY, old, superClass);
	}
	
	protected JaxbClass buildSuperClass() {
		HashSet<JavaResourceType> visited = new HashSet<JavaResourceType>();
		visited.add(this.getJavaResourceType());
		JaxbClass spc = this.getSuperClass(this.getJavaResourceType().getSuperclassQualifiedName(), visited);
		if (spc == null) {
			return null;
		}
		if (CollectionTools.contains(spc.getInheritanceHierarchy(), this)) {
			return null;  // short-circuit in this case, we have circular inheritance
		}
		return spc;
	}
	
	/**
	 * The JPA spec allows non-persistent types in a persistent type's
	 * inheritance hierarchy. We check for a persistent type with the
	 * specified name in the persistence unit. If it is not found we use
	 * resource persistent type and look for *its* super type.
	 * 
	 * The 'visited' collection is used to detect a cycle in the *resource* type
	 * inheritance hierarchy and prevent the resulting stack overflow.
	 * Any cycles in the *context* type inheritance hierarchy are handled in
	 * #buildSuperPersistentType().
	 */
	protected JaxbClass getSuperClass(String typeName, Collection<JavaResourceType> visited) {
		if (typeName == null) {
			return null;
		}
		JavaResourceType resourceType = (JavaResourceType) this.getJaxbProject().getJavaResourceType(typeName, JavaResourceAbstractType.Kind.TYPE);
		if ((resourceType == null) || visited.contains(resourceType)) {
			return null;
		}
		visited.add(resourceType);
		JaxbClass spc = this.getClass(typeName);
		return (spc != null && resourceType.isMapped()) ? spc : this.getSuperClass(resourceType.getSuperclassQualifiedName(), visited);  // recurse
	}
	
	protected JaxbClass getClass(String fullyQualifiedTypeName) {
		return this.getParent().getClass(fullyQualifiedTypeName);
	}
	
	
	// ********** inheritance **********
	
	public Iterable<JaxbClass> getInheritanceHierarchy() {
		return this.getInheritanceHierarchyOf(this);
	}
	
	public Iterable<JaxbClass> getAncestors() {
		return this.getInheritanceHierarchyOf(this.superClass);
	}
	
	protected Iterable<JaxbClass> getInheritanceHierarchyOf(JaxbClass start) {
		// using a chain iterator to traverse up the inheritance tree
		return new ChainIterable<JaxbClass>(start) {
			@Override
			protected JaxbClass nextLink(JaxbClass jaxbClass) {
				return jaxbClass.getSuperClass();
			}
		};
	}
	
	// ********** access type **********
	
	public XmlAccessType getAccessType() {
		return (this.specifiedAccessType != null) ? this.specifiedAccessType : this.defaultAccessType;
	}
	
	public XmlAccessType getSpecifiedAccessType() {
		return this.specifiedAccessType;
	}
	
	public void setSpecifiedAccessType(XmlAccessType access) {
		this.getAccessorTypeAnnotation().setValue(XmlAccessType.toJavaResourceModel(access));
		this.setSpecifiedAccessType_(access);
	}
	
	protected void setSpecifiedAccessType_(XmlAccessType access) {
		XmlAccessType old = this.specifiedAccessType;
		this.specifiedAccessType = access;
		this.firePropertyChanged(SPECIFIED_ACCESS_TYPE_PROPERTY, old, access);
	}
	
	public XmlAccessType getDefaultAccessType() {
		return this.defaultAccessType;
	}
	
	protected void setDefaultAccessType(XmlAccessType access) {
		XmlAccessType old = this.defaultAccessType;
		this.defaultAccessType = access;
		this.firePropertyChanged(DEFAULT_ACCESS_TYPE_PROPERTY, old, access);
	}
	
	protected XmlAccessType getResourceAccessType() {
		return XmlAccessType.fromJavaResourceModel(this.getAccessorTypeAnnotation().getValue());
	}
	
	protected XmlAccessorTypeAnnotation getAccessorTypeAnnotation() {
		return (XmlAccessorTypeAnnotation) getJavaResourceType().getNonNullAnnotation(XmlAccessorTypeAnnotation.ANNOTATION_NAME);
	}
	
	/**
	 * If there is a @XmlAccessorType on a class, then it is used.
	 * Otherwise, if a @XmlAccessorType exists on one of its super classes, then it is inherited.
	 * Otherwise, the @XmlAccessorType on a package is inherited. 	
	 */
	protected XmlAccessType buildDefaultAccessType() {
		XmlAccessType superAccessType = this.getSuperClassAccessType();
		if (superAccessType != null) {
			return superAccessType;
		}
		XmlAccessType packageAccessType = getPackageAccessType();
		if (packageAccessType != null) {
			return packageAccessType;
		}
		return XmlAccessType.PUBLIC_MEMBER;
	}
	
	protected XmlAccessType getSuperClassAccessType() {
		JaxbClass superClass = this.getSuperClass();
		return superClass == null ? null : superClass.getSpecifiedAccessType();
	}
	
	protected XmlAccessType getPackageAccessType() {
		JaxbPackageInfo packageInfo = this.getPackageInfo();
		return packageInfo == null ? null : packageInfo.getAccessType();
	}
	
	
	// ********** access order **********
	
	public XmlAccessOrder getAccessOrder() {
		return (this.specifiedAccessOrder != null) ? this.specifiedAccessOrder : this.defaultAccessOrder;
	}
	
	public XmlAccessOrder getSpecifiedAccessOrder() {
		return this.specifiedAccessOrder;
	}
	
	public void setSpecifiedAccessOrder(XmlAccessOrder accessOrder) {
		this.getAccessorOrderAnnotation().setValue(XmlAccessOrder.toJavaResourceModel(accessOrder));
		this.setSpecifiedAccessOrder_(accessOrder);
	}
	
	protected void setSpecifiedAccessOrder_(XmlAccessOrder accessOrder) {
		XmlAccessOrder old = this.specifiedAccessOrder;
		this.specifiedAccessOrder = accessOrder;
		this.firePropertyChanged(SPECIFIED_ACCESS_ORDER_PROPERTY, old, accessOrder);
	}
	
	public XmlAccessOrder getDefaultAccessOrder() {
		return this.defaultAccessOrder;
	}
	
	protected void setDefaultAccessOrder(XmlAccessOrder accessOrder) {
		XmlAccessOrder old = this.defaultAccessOrder;
		this.defaultAccessOrder = accessOrder;
		this.firePropertyChanged(DEFAULT_ACCESS_ORDER_PROPERTY, old, accessOrder);
	}
	
	protected XmlAccessOrder getResourceAccessOrder() {
		return XmlAccessOrder.fromJavaResourceModel(this.getAccessorOrderAnnotation().getValue());
	}
	
	protected XmlAccessorOrderAnnotation getAccessorOrderAnnotation() {
		return (XmlAccessorOrderAnnotation) getJavaResourceType().getNonNullAnnotation(XmlAccessorOrderAnnotation.ANNOTATION_NAME);
	}
	
	/**
    * If there is a @XmlAccessorOrder on a class, then it is used.
    * Otherwise, if a @XmlAccessorOrder exists on one of its super classes, then it is inherited (by the virtue of Inherited)
    * Otherwise, the @XmlAccessorOrder on the package of the class is used, if it's there.
    * Otherwise XmlAccessOrder.UNDEFINED. 
  	*/
	protected XmlAccessOrder buildDefaultAccessOrder() {
		XmlAccessOrder superAccessOrder = this.getSuperClassAccessOrder();
		if (superAccessOrder != null) {
			return superAccessOrder;
		}
		XmlAccessOrder packageAccessOrder = getPackageAccessOrder();
		if (packageAccessOrder != null) {
			return packageAccessOrder;
		}
		return XmlAccessOrder.UNDEFINED;
	}
	
	protected XmlAccessOrder getSuperClassAccessOrder() {
		JaxbClass superClass = this.getSuperClass();
		return superClass == null ? null : superClass.getSpecifiedAccessOrder();
	}
	
	protected XmlAccessOrder getPackageAccessOrder() {
		JaxbPackageInfo packageInfo = this.getPackageInfo();
		return packageInfo == null ? null : packageInfo.getAccessOrder();
	}
	
	
	//****************** XmlJavaTypeAdapter *********************
	
	public XmlAdaptable buildXmlAdaptable() {
		return new GenericJavaXmlAdaptable(this, new XmlAdaptable.Owner() {
			public JavaResourceAnnotatedElement getResource() {
				return getJavaResourceType();
			}
			public XmlJavaTypeAdapter buildXmlJavaTypeAdapter(XmlJavaTypeAdapterAnnotation adapterAnnotation) {
				return GenericJavaPersistentClass.this.buildXmlJavaTypeAdapter(adapterAnnotation);
			}
			public void fireXmlAdapterChanged(XmlJavaTypeAdapter oldAdapter, XmlJavaTypeAdapter newAdapter) {
				GenericJavaPersistentClass.this.firePropertyChanged(XML_JAVA_TYPE_ADAPTER_PROPERTY, oldAdapter, newAdapter);
			}
		});
	}
	
	public XmlJavaTypeAdapter getXmlJavaTypeAdapter() {
		return this.xmlAdaptable.getXmlJavaTypeAdapter();
	}
	
	public XmlJavaTypeAdapter addXmlJavaTypeAdapter() {
		return this.xmlAdaptable.addXmlJavaTypeAdapter();
	}
	
	protected XmlJavaTypeAdapter buildXmlJavaTypeAdapter(XmlJavaTypeAdapterAnnotation xmlJavaTypeAdapterAnnotation) {
		return new GenericJavaTypeXmlJavaTypeAdapter(this, xmlJavaTypeAdapterAnnotation);
	}
	
	public void removeXmlJavaTypeAdapter() {
		this.xmlAdaptable.removeXmlJavaTypeAdapter();
	}
	
	
	// **************** xml see also ******************************************
	
	protected XmlSeeAlsoAnnotation getXmlSeeAlsoAnnotation() {
		return (XmlSeeAlsoAnnotation) getJavaResourceType().getAnnotation(JAXB.XML_SEE_ALSO);
	}
	
	protected void initXmlSeeAlso() {
		XmlSeeAlsoAnnotation annotation = getXmlSeeAlsoAnnotation();
		this.xmlSeeAlso = (annotation == null) ?
				null
				: buildXmlSeeAlso(annotation);
	}
	
	protected XmlSeeAlso buildXmlSeeAlso(XmlSeeAlsoAnnotation annotation) {
		return new GenericJavaXmlSeeAlso(this, annotation);
	}
	
	public XmlSeeAlso getXmlSeeAlso() {
		return this.xmlSeeAlso;
	}
	
	public XmlSeeAlso addXmlSeeAlso() {
		if (this.xmlSeeAlso != null) {
			throw new IllegalStateException();
		}
		XmlSeeAlsoAnnotation annotation = (XmlSeeAlsoAnnotation) getJavaResourceType().addAnnotation(JAXB.XML_SEE_ALSO);
		
		XmlSeeAlso xmlSeeAlso = buildXmlSeeAlso(annotation);
		setXmlSeeAlso_(xmlSeeAlso);
		return xmlSeeAlso;
	}
	
	protected void setXmlSeeAlso_(XmlSeeAlso xmlSeeAlso) {
		XmlSeeAlso old = this.xmlSeeAlso;
		this.xmlSeeAlso = xmlSeeAlso;
		firePropertyChanged(XML_SEE_ALSO_PROPERTY, old, xmlSeeAlso);
	}
	
	public void removeXmlSeeAlso() {
		if (this.xmlSeeAlso == null) {
			throw new IllegalStateException();
		}
		getJavaResourceType().removeAnnotation(JAXB.XML_SEE_ALSO);
		setXmlSeeAlso_(null);
	}
	
	protected void syncXmlSeeAlso() {
		XmlSeeAlsoAnnotation annotation = getXmlSeeAlsoAnnotation();
		if (annotation != null) {
			if (this.xmlSeeAlso != null) {
				this.xmlSeeAlso.synchronizeWithResourceModel();
			}
			else {
				setXmlSeeAlso_(buildXmlSeeAlso(annotation));
			}
		}
		else {
			setXmlSeeAlso_(null);
		}
	}
	
	protected void updateXmlSeeAlso() {
		if (this.xmlSeeAlso != null) {
			this.xmlSeeAlso.update();
		}
	}
	
	
	// ********** attributes **********
	
	public Iterable<JaxbPersistentAttribute> getAttributes() {
		return this.attributesContainer.getAttributes();
	}
	
	public int getAttributesSize() {
		return this.attributesContainer.getAttributesSize();
	}
	
	protected JaxbAttributesContainer.Owner buildAttributesContainerOwner() {
		return new JaxbAttributesContainer.Owner() {
			public XmlAccessType getAccessType() {
				return GenericJavaPersistentClass.this.getAccessType();
			}
			
			public void fireAttributeAdded(JaxbPersistentAttribute attribute) {
				GenericJavaPersistentClass.this.fireItemAdded(ATTRIBUTES_COLLECTION, attribute);
			}
			
			public void fireAttributeRemoved(JaxbPersistentAttribute attribute) {
				GenericJavaPersistentClass.this.fireItemRemoved(ATTRIBUTES_COLLECTION, attribute);
			}
		};
	}
	
	
	// ********** inherited attributes **********
	
	public Iterable<JaxbPersistentAttribute> getInheritedAttributes() {
		return new CompositeIterable<JaxbPersistentAttribute>(this.getInheritedAttributeSets());
	}
	
	protected Iterable<Iterable<JaxbPersistentAttribute>> getInheritedAttributeSets() {
		return new TransformationIterable<JaxbAttributesContainer, Iterable<JaxbPersistentAttribute>>(this.getInheritedAttributesContainers()) {
			@Override
			protected Iterable<JaxbPersistentAttribute> transform(JaxbAttributesContainer attributesContainer) {
				return attributesContainer.getAttributes();
			}
		};
	}
	
	protected Iterable<JaxbAttributesContainer> getInheritedAttributesContainers() {
		return new LiveCloneIterable<JaxbAttributesContainer>(this.inheritedAttributesContainers.values());  // read-only
	}
	
	public int getInheritedAttributesSize() {
		int size = 0;
		for (JaxbAttributesContainer attributesContainer : getInheritedAttributesContainers()) {
			size += attributesContainer.getAttributesSize();
		}
		return size;
	}
	
	protected void initializeInheritedAttributes() {
		this.addInheritedAttributesContainer(this.getSuperClass());
	}
	
	protected void addInheritedAttributesContainer(JaxbClass superClass) {
		if (superClass != null) {
			if (superClass.getKind() == Kind.TRANSIENT) {
				this.inheritedAttributesContainers.put(superClass, this.buildInheritedAttributesContainer(superClass));
				this.addInheritedAttributesContainer(superClass.getSuperClass());
			}
		}
	}
	
	protected JaxbAttributesContainer buildInheritedAttributesContainer(JaxbClass jaxbClass) {
		return new GenericJavaAttributesContainer(this, buildInheritedAttributesContainerOwner(), jaxbClass.getJavaResourceType());
	}
	
	protected JaxbAttributesContainer.Owner buildInheritedAttributesContainerOwner() {
		return new JaxbAttributesContainer.Owner() {
			public XmlAccessType getAccessType() {
				return GenericJavaPersistentClass.this.getAccessType();
			}
			
			public void fireAttributeAdded(JaxbPersistentAttribute attribute) {
				GenericJavaPersistentClass.this.fireItemAdded(INHERITED_ATTRIBUTES_COLLECTION, attribute);
			}
			
			public void fireAttributeRemoved(JaxbPersistentAttribute attribute) {
				GenericJavaPersistentClass.this.fireItemRemoved(INHERITED_ATTRIBUTES_COLLECTION, attribute);
			}
		};
	}
	
	protected void syncInheritedAttributes() {
		for (JaxbAttributesContainer attributesContainer : this.inheritedAttributesContainers.values()) {
			attributesContainer.synchronizeWithResourceModel();
		}
	}
	
	/**
	 * The attributes are synchronized during the <em>update</em> because
	 * the list of resource attributes is determined by the access type
	 * which can be controlled in a number of different places....
	 */
	protected void updateInheritedAttributes() {
		HashSet<JaxbClass> contextSuperclasses = CollectionTools.set(this.inheritedAttributesContainers.keySet());
		for (JaxbClass superClass : getAncestors()) {
			if (superClass.getKind() == Kind.TRANSIENT) {
				boolean match = false;
				for (Iterator<JaxbClass> stream = contextSuperclasses.iterator(); stream.hasNext(); ) {
					JaxbClass contextSuperclass = stream.next();
					if (contextSuperclass == superClass) {
						stream.remove();
						this.inheritedAttributesContainers.get(contextSuperclass).update();
						match = true;
						break;
					}
				}
				if ( ! match) {
					JaxbAttributesContainer container = this.buildInheritedAttributesContainer(superClass);
					this.inheritedAttributesContainers.put(superClass, container);
					this.fireItemsAdded(INHERITED_ATTRIBUTES_COLLECTION, CollectionTools.collection(container.getAttributes()));
				}
			}
		}
		
		for (JaxbClass superClass : contextSuperclasses) {
			JaxbAttributesContainer container = this.inheritedAttributesContainers.remove(superClass);
			this.fireItemsRemoved(INHERITED_ATTRIBUTES_COLLECTION, CollectionTools.collection(container.getAttributes()));
		}
	}
	
	public boolean isInherited(JaxbPersistentAttribute attribute) {
		if (attribute.getParent() != this) {
			throw new IllegalArgumentException("The attribute is not owned by this GenericJavaPersistentClass"); //$NON-NLS-1$
		}
		return !CollectionTools.contains(this.getAttributes(), attribute);
	}
	
	public String getJavaResourceAttributeOwningTypeName(JaxbPersistentAttribute attribute) {
		if (attribute.getParent() != this) {
			throw new IllegalArgumentException("The attribute is not owned by this GenericJavaPersistentClass"); //$NON-NLS-1$
		}
		for (JaxbClass inheritedClass : this.inheritedAttributesContainers.keySet()) {
			if (CollectionTools.contains(this.inheritedAttributesContainers.get(inheritedClass).getAttributes(), attribute)) {
				return inheritedClass.getSimpleName();
			}
		}
		throw new IllegalArgumentException("The attribute is not an inherited attribute"); //$NON-NLS-1$
	}
	
	
	// ********** content assist **********
	
	@Override
	public Iterable<String> getJavaCompletionProposals(int pos, Filter<String> filter, CompilationUnit astRoot) {
		Iterable<String> result = super.getJavaCompletionProposals(pos, filter, astRoot);
		if (!CollectionTools.isEmpty(result)) {
			return result;
		}
		for (JaxbPersistentAttribute attribute : this.getAttributes()) {
			result = attribute.getJavaCompletionProposals(pos, filter, astRoot);
			if (!CollectionTools.isEmpty(result)) {
				return result;
			}
		}
		return EmptyIterable.instance();
	}
	
	// ********** validation **********
	
	@Override
	public void validate(List<IMessage> messages, IReporter reporter, CompilationUnit astRoot) {
		super.validate(messages, reporter, astRoot);
		this.xmlAdaptable.validate(messages, reporter, astRoot);
		this.validateXmlAnyAttributeMapping(messages, astRoot);
		this.validateXmlAnyElementMapping(messages, astRoot);
		this.validateXmlValueMapping(messages, astRoot);
		this.validateXmlIDs(messages, astRoot);
		for (JaxbPersistentAttribute attribute : getAttributes()) {
			attribute.validate(messages, reporter, astRoot);
		}
	}
	
	protected void validateXmlValueMapping(List<IMessage> messages, CompilationUnit astRoot) {
		String xmlValueMapping = null;
		for (JaxbPersistentAttribute attribute : getAttributes()) {
			if (attribute.getMappingKey() == MappingKeys.XML_VALUE_ATTRIBUTE_MAPPING_KEY) {
				if (xmlValueMapping != null) {
					messages.add(
						DefaultValidationMessages.buildMessage(
							IMessage.HIGH_SEVERITY,
							JaxbValidationMessages.MULTIPLE_XML_VALUE_MAPPINGS_DEFINED,
							new String[] {attribute.getName(), xmlValueMapping},
							attribute.getMapping(),
							attribute.getMapping().getValidationTextRange(astRoot)));
				}
				else {
					xmlValueMapping = attribute.getName();
				}
			}
		}
		if (xmlValueMapping != null) {
			for (JaxbPersistentAttribute attribute : getAttributes()) {
				if (attribute.getName() != xmlValueMapping) {
					if (attribute.getMappingKey() != MappingKeys.XML_ATTRIBUTE_ATTRIBUTE_MAPPING_KEY 
						&& attribute.getMappingKey() != MappingKeys.XML_TRANSIENT_ATTRIBUTE_MAPPING_KEY) {
						messages.add(
							DefaultValidationMessages.buildMessage(
								IMessage.HIGH_SEVERITY,
								JaxbValidationMessages.XML_VALUE_MAPPING_WITH_NON_XML_ATTRIBUTE_MAPPING_DEFINED,
								new String[] {attribute.getName(), xmlValueMapping},
								attribute.getMapping(),
								attribute.getMapping().getValidationTextRange(astRoot)));					
					}
				}
			}
		}
	}
	
	protected void validateXmlAnyAttributeMapping(List<IMessage> messages, CompilationUnit astRoot) {
		String xmlAnyAttributeMapping = null;
		for (JaxbPersistentAttribute attribute : getAttributes()) {
			if (attribute.getMappingKey() == MappingKeys.XML_ANY_ATTRIBUTE_ATTRIBUTE_MAPPING_KEY) {
				if (xmlAnyAttributeMapping != null) {
					messages.add(
						DefaultValidationMessages.buildMessage(
							IMessage.HIGH_SEVERITY,
							JaxbValidationMessages.MULTIPLE_XML_ANY_ATTRIBUTE_MAPPINGS_DEFINED,
							new String[] {attribute.getName(), xmlAnyAttributeMapping},
							attribute.getMapping(),
							attribute.getMapping().getValidationTextRange(astRoot)));
				}
				else {
					xmlAnyAttributeMapping = attribute.getName();
				}
			}
		}
	}
	
	protected void validateXmlAnyElementMapping(List<IMessage> messages, CompilationUnit astRoot) {
		String xmlAnyElementMapping = null;
		for (JaxbPersistentAttribute attribute : getAttributes()) {
			if (attribute.getMappingKey() == MappingKeys.XML_ANY_ELEMENT_ATTRIBUTE_MAPPING_KEY) {
				if (xmlAnyElementMapping != null) {
					messages.add(
						DefaultValidationMessages.buildMessage(
							IMessage.HIGH_SEVERITY,
							JaxbValidationMessages.MULTIPLE_XML_ANY_ELEMENT_MAPPINGS_DEFINED,
							new String[] {attribute.getName(), xmlAnyElementMapping},
							attribute.getMapping(),
							attribute.getMapping().getValidationTextRange(astRoot)));
				}
				else {
					xmlAnyElementMapping = attribute.getName();
				}
			}
		}
	}
	
	protected void validateXmlIDs(List<IMessage> messages, CompilationUnit astRoot) {
		String xmlIdMapping = null;
		for (JaxbContainmentMapping containmentMapping : getContainmentMappingsWithXmlID()) {
			if (xmlIdMapping != null) {
				messages.add(
					DefaultValidationMessages.buildMessage(
						IMessage.HIGH_SEVERITY,
						JaxbValidationMessages.MULTIPLE_XML_IDS_DEFINED,
						new String[] {containmentMapping.getParent().getName(), xmlIdMapping},
						containmentMapping,
						containmentMapping.getValidationTextRange(astRoot)));
			}
			else {
				xmlIdMapping = containmentMapping.getParent().getName();
			}
		}
	}
	
	protected Iterable<JaxbContainmentMapping> getContainmentMappingsWithXmlID(){
		return new FilteringIterable<JaxbContainmentMapping>(this.getContainmentMappings()){
			@Override
			protected boolean accept(JaxbContainmentMapping containmentMapping) {
				return containmentMapping.getXmlID() != null;
			}
		};
	}
	
	protected Iterable<JaxbContainmentMapping> getContainmentMappings() {
		return new SubIterableWrapper<JaxbAttributeMapping, JaxbContainmentMapping>(this.getContainmentMappings_());
	}
	
	protected Iterable<JaxbAttributeMapping> getContainmentMappings_(){
		return new FilteringIterable<JaxbAttributeMapping>(this.getAttributeMappings()){
			@Override
			protected boolean accept(JaxbAttributeMapping attributeMapping) {
				return (attributeMapping.getKey() == MappingKeys.XML_ELEMENT_ATTRIBUTE_MAPPING_KEY
					|| attributeMapping.getKey() == MappingKeys.XML_ATTRIBUTE_ATTRIBUTE_MAPPING_KEY);
			}
		};
	}
	
	private Iterable<? extends JaxbAttributeMapping> getAttributeMappings() {
		return new TransformationIterable<JaxbPersistentAttribute, JaxbAttributeMapping>(this.getAttributes()) {
			@Override
			protected JaxbAttributeMapping transform(JaxbPersistentAttribute attribute) {
				return attribute.getMapping();
			}
		};
	}

	public boolean containsXmlId() {
		return !CollectionTools.isEmpty(getContainmentMappingsWithXmlID());
	}
}
