281389 - added java resource model support for joinTable on AssociationOverride annotation
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/platform/GenericJpaAnnotationDefinitionProvider.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/platform/GenericJpaAnnotationDefinitionProvider.java
index e76c2cc..c893b12 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/platform/GenericJpaAnnotationDefinitionProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/platform/GenericJpaAnnotationDefinitionProvider.java
@@ -89,7 +89,6 @@
 		definitions.add(AssociationOverrideAnnotationDefinition.instance());
 		definitions.add(AssociationOverridesAnnotationDefinition.instance());
 		definitions.add(AttributeOverrideAnnotationDefinition.instance());
-		definitions.add(AttributeOverrideAnnotationDefinition.instance());
 		definitions.add(AttributeOverridesAnnotationDefinition.instance());
 		definitions.add(DiscriminatorColumnAnnotationDefinition.instance());
 		definitions.add(DiscriminatorValueAnnotationDefinition.instance());
@@ -103,7 +102,7 @@
 		definitions.add(PrimaryKeyJoinColumnsAnnotationDefinition.instance());
 		definitions.add(SecondaryTableAnnotationDefinition.instance());
 		definitions.add(SecondaryTablesAnnotationDefinition.instance());
-		definitions.add(this.sequenceGeneratorAnnotationDefinition());
+		definitions.add(SequenceGeneratorAnnotationDefinition.instance());
 		definitions.add(TableAnnotationDefinition.instance());
 		definitions.add(TableGeneratorAnnotationDefinition.instance());
 	}
@@ -139,12 +138,9 @@
 		definitions.add(OrderByAnnotationDefinition.instance());
 		definitions.add(PrimaryKeyJoinColumnAnnotationDefinition.instance());
 		definitions.add(PrimaryKeyJoinColumnsAnnotationDefinition.instance());
-		definitions.add(this.sequenceGeneratorAnnotationDefinition());
+		definitions.add(SequenceGeneratorAnnotationDefinition.instance());
 		definitions.add(TableGeneratorAnnotationDefinition.instance());
 		definitions.add(TemporalAnnotationDefinition.instance());
 	}
-	
-	protected  AnnotationDefinition sequenceGeneratorAnnotationDefinition() {
-		return SequenceGeneratorAnnotationDefinition.instance();
-	}
+
 }
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JoinTableAnnotationDefinition.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JoinTableAnnotationDefinition.java
index ba5e22d..45bf125 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JoinTableAnnotationDefinition.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/JoinTableAnnotationDefinition.java
@@ -14,7 +14,6 @@
 import org.eclipse.jpt.core.internal.resource.java.source.SourceJoinTableAnnotation;
 import org.eclipse.jpt.core.resource.java.Annotation;
 import org.eclipse.jpt.core.resource.java.AnnotationDefinition;
-import org.eclipse.jpt.core.resource.java.JavaResourcePersistentAttribute;
 import org.eclipse.jpt.core.resource.java.JavaResourcePersistentMember;
 import org.eclipse.jpt.core.resource.java.JoinTableAnnotation;
 import org.eclipse.jpt.core.utility.jdt.Member;
@@ -47,7 +46,7 @@
 	}
 
 	public Annotation buildNullAnnotation(JavaResourcePersistentMember parent) {
-		return new NullJoinTableAnnotation((JavaResourcePersistentAttribute) parent);
+		return new NullJoinTableAnnotation(parent);
 	}
 
 	public Annotation buildAnnotation(JavaResourcePersistentMember parent, IAnnotation jdtAnnotation) {
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/NullBaseTableAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/NullBaseTableAnnotation.java
index 3ce4cf3..b0cec8a 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/NullBaseTableAnnotation.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/NullBaseTableAnnotation.java
@@ -13,7 +13,7 @@
 
 import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jpt.core.resource.java.BaseTableAnnotation;
-import org.eclipse.jpt.core.resource.java.JavaResourcePersistentMember;
+import org.eclipse.jpt.core.resource.java.JavaResourceNode;
 import org.eclipse.jpt.core.resource.java.UniqueConstraintAnnotation;
 import org.eclipse.jpt.core.utility.TextRange;
 import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator;
@@ -26,14 +26,12 @@
 	extends NullAnnotation
 	implements BaseTableAnnotation
 {
-	protected NullBaseTableAnnotation(JavaResourcePersistentMember parent) {
+	protected NullBaseTableAnnotation(JavaResourceNode parent) {
 		super(parent);
 	}
+	
+	protected abstract BaseTableAnnotation buildAnnotation();
 
-	@Override
-	protected BaseTableAnnotation buildSupportingAnnotation() {
-		return (BaseTableAnnotation) super.buildSupportingAnnotation();
-	}
 
 	// ***** name
 	public String getName() {
@@ -42,7 +40,7 @@
 
 	public void setName(String name) {
 		if (name != null) {
-			this.buildSupportingAnnotation().setName(name);
+			this.buildAnnotation().setName(name);
 		}
 	}
 
@@ -61,7 +59,7 @@
 
 	public void setSchema(String schema) {
 		if (schema != null) {
-			this.buildSupportingAnnotation().setSchema(schema);
+			this.buildAnnotation().setSchema(schema);
 		}
 	}
 
@@ -80,7 +78,7 @@
 
 	public void setCatalog(String catalog) {
 		if (catalog != null) {
-			this.buildSupportingAnnotation().setCatalog(catalog);
+			this.buildAnnotation().setCatalog(catalog);
 		}
 	}
 
@@ -110,7 +108,7 @@
 	}
 
 	public UniqueConstraintAnnotation addUniqueConstraint(int index) {
-		return this.buildSupportingAnnotation().addUniqueConstraint(index);
+		return this.buildAnnotation().addUniqueConstraint(index);
 	}
 
 	public void moveUniqueConstraint(int targetIndex, int sourceIndex) {
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/NullJoinTableAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/NullJoinTableAnnotation.java
index b113a2c..74fbd67 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/NullJoinTableAnnotation.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/NullJoinTableAnnotation.java
@@ -11,7 +11,7 @@
 
 import java.util.ListIterator;
 
-import org.eclipse.jpt.core.resource.java.JavaResourcePersistentAttribute;
+import org.eclipse.jpt.core.resource.java.JavaResourceNode;
 import org.eclipse.jpt.core.resource.java.JoinColumnAnnotation;
 import org.eclipse.jpt.core.resource.java.JoinTableAnnotation;
 import org.eclipse.jpt.utility.internal.iterators.EmptyListIterator;
@@ -19,11 +19,11 @@
 /**
  * javax.persistence.JoinTable
  */
-public final class NullJoinTableAnnotation
+public class NullJoinTableAnnotation
 	extends NullBaseTableAnnotation
 	implements JoinTableAnnotation
 {	
-	protected NullJoinTableAnnotation(JavaResourcePersistentAttribute parent) {
+	public NullJoinTableAnnotation(JavaResourceNode parent) {
 		super(parent);
 	}
 
@@ -32,8 +32,8 @@
 	}
 
 	@Override
-	protected JoinTableAnnotation buildSupportingAnnotation() {
-		return (JoinTableAnnotation) super.buildSupportingAnnotation();
+	protected JoinTableAnnotation buildAnnotation() {
+		return (JoinTableAnnotation) this.buildSupportingAnnotation();
 	}
 
 	// ***** join columns
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/NullTableAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/NullTableAnnotation.java
index 41093b9..a892bec 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/NullTableAnnotation.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/NullTableAnnotation.java
@@ -23,6 +23,11 @@
 		super(parent);
 	}
 
+	@Override
+	protected TableAnnotation buildAnnotation() {
+		return (TableAnnotation) buildSupportingAnnotation();
+	}
+	
 	public String getAnnotationName() {
 		return ANNOTATION_NAME;
 	}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryAssociationOverrideAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryAssociationOverrideAnnotation.java
index 5eeed71..8e97c13 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryAssociationOverrideAnnotation.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryAssociationOverrideAnnotation.java
@@ -22,7 +22,7 @@
 /**
  * javax.persistence.AssociationOverride
  */
-public final class BinaryAssociationOverrideAnnotation
+public class BinaryAssociationOverrideAnnotation
 	extends BinaryOverrideAnnotation
 	implements NestableAssociationOverrideAnnotation
 {
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryAssociationOverridesAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryAssociationOverridesAnnotation.java
index 2e56b9d..07c5b99 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryAssociationOverridesAnnotation.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/binary/BinaryAssociationOverridesAnnotation.java
@@ -22,7 +22,7 @@
 /**
  * javax.persistence.AssociationOverrides
  */
-public final class BinaryAssociationOverridesAnnotation
+public class BinaryAssociationOverridesAnnotation
 	extends BinaryContainerAnnotation<NestableAssociationOverrideAnnotation>
 	implements AssociationOverridesAnnotation
 {
@@ -50,11 +50,15 @@
 		Object[] jdtAssociationOverrides = this.getJdtMemberValues(JPA.ASSOCIATION_OVERRIDES__VALUE);
 		Vector<NestableAssociationOverrideAnnotation> result = new Vector<NestableAssociationOverrideAnnotation>(jdtAssociationOverrides.length);
 		for (Object jdtAssociationOverride : jdtAssociationOverrides) {
-			result.add(new BinaryAssociationOverrideAnnotation(this, (IAnnotation) jdtAssociationOverride));
+			result.add(buildAssociationOverride(jdtAssociationOverride));
 		}
 		return result;
 	}
 
+	protected NestableAssociationOverrideAnnotation buildAssociationOverride(Object jdtAssociationOverride) {
+		return new BinaryAssociationOverrideAnnotation(this, (IAnnotation) jdtAssociationOverride);
+	}
+	
 	@Override
 	public void update() {
 		super.update();
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceAssociationOverrideAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceAssociationOverrideAnnotation.java
index e5b35c7..c3c9fe8 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceAssociationOverrideAnnotation.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceAssociationOverrideAnnotation.java
@@ -37,7 +37,7 @@
 /**
  * javax.persistence.AssociationOverride
  */
-public final class SourceAssociationOverrideAnnotation
+public class SourceAssociationOverrideAnnotation
 	extends SourceOverrideAnnotation
 	implements NestableAssociationOverrideAnnotation
 {
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceAssociationOverridesAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceAssociationOverridesAnnotation.java
index 080364c..6ff8f43 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceAssociationOverridesAnnotation.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceAssociationOverridesAnnotation.java
@@ -27,7 +27,7 @@
 /**
  * javax.persistence.AssociationOverrides
  */
-public final class SourceAssociationOverridesAnnotation
+public class SourceAssociationOverridesAnnotation
 	extends SourceAnnotation<Member>
 	implements AssociationOverridesAnnotation
 {
@@ -90,7 +90,7 @@
 		return associationOverride;
 	}
 
-	private NestableAssociationOverrideAnnotation buildAssociationOverride(int index) {
+	protected NestableAssociationOverrideAnnotation buildAssociationOverride(int index) {
 		return SourceAssociationOverrideAnnotation.createNestedAssociationOverride(this, this.member, index, this.daa);
 	}
 
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceBaseTableAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceBaseTableAnnotation.java
index 27da9bb..5ff3c9d 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceBaseTableAnnotation.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceBaseTableAnnotation.java
@@ -15,10 +15,13 @@
 import org.eclipse.jdt.core.dom.Annotation;
 import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jpt.core.internal.utility.jdt.MemberAnnotationAdapter;
+import org.eclipse.jpt.core.internal.utility.jdt.NestedIndexedDeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.internal.utility.jdt.ShortCircuitAnnotationElementAdapter;
 import org.eclipse.jpt.core.resource.java.AnnotationContainer;
 import org.eclipse.jpt.core.resource.java.BaseTableAnnotation;
+import org.eclipse.jpt.core.resource.java.JPA;
 import org.eclipse.jpt.core.resource.java.JavaResourceNode;
+import org.eclipse.jpt.core.resource.java.NestableAnnotation;
 import org.eclipse.jpt.core.resource.java.NestableUniqueConstraintAnnotation;
 import org.eclipse.jpt.core.resource.java.UniqueConstraintAnnotation;
 import org.eclipse.jpt.core.utility.TextRange;
@@ -26,6 +29,7 @@
 import org.eclipse.jpt.core.utility.jdt.AnnotationElementAdapter;
 import org.eclipse.jpt.core.utility.jdt.DeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.utility.jdt.DeclarationAnnotationElementAdapter;
+import org.eclipse.jpt.core.utility.jdt.IndexedDeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.utility.jdt.Member;
 import org.eclipse.jpt.utility.internal.CollectionTools;
 import org.eclipse.jpt.utility.internal.StringTools;
@@ -228,7 +232,13 @@
 		return uniqueConstraint;
 	}
 
-	abstract NestableUniqueConstraintAnnotation buildUniqueConstraint(int index);
+	NestableUniqueConstraintAnnotation buildUniqueConstraint(int index) {
+		return new SourceUniqueConstraintAnnotation(this, this.member, buildUniqueConstraintAnnotationAdapter(index));
+	}
+
+	IndexedDeclarationAnnotationAdapter buildUniqueConstraintAnnotationAdapter(int index) {
+		return new NestedIndexedDeclarationAnnotationAdapter(this.daa, getUniqueConstraintsElementName(), index, JPA.UNIQUE_CONSTRAINT);
+	}
 
 	void uniqueConstraintAdded(int index, NestableUniqueConstraintAnnotation constraint) {
 		this.fireItemAdded(UNIQUE_CONSTRAINTS_LIST, index, constraint);
@@ -258,7 +268,20 @@
 		this.fireItemRemoved(UNIQUE_CONSTRAINTS_LIST, index, constraint);
 	}
 
+	
+	// ********** NestableAnnotation implementation **********
 
+	protected void initializeFrom(NestableAnnotation oldAnnotation) {
+		BaseTableAnnotation oldTable = (BaseTableAnnotation) oldAnnotation;
+		this.setName(oldTable.getName());
+		this.setSchema(oldTable.getSchema());
+		this.setCatalog(oldTable.getCatalog());
+		for (UniqueConstraintAnnotation oldUniqueConstraint : CollectionTools.iterable(oldTable.uniqueConstraints())) {
+			NestableUniqueConstraintAnnotation newUniqueConstraint = this.addUniqueConstraint(oldTable.indexOfUniqueConstraint(oldUniqueConstraint));
+			newUniqueConstraint.initializeFrom((NestableAnnotation) oldUniqueConstraint);
+		}
+	}
+	
 	// ********** unique constraint container **********
 
 	/**
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceJoinColumnAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceJoinColumnAnnotation.java
index 201ada6..cf9f24a 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceJoinColumnAnnotation.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceJoinColumnAnnotation.java
@@ -178,23 +178,6 @@
 		return new NestedIndexedDeclarationAnnotationAdapter(joinColumnsAdapter, index, JPA.JOIN_COLUMN);
 	}
 
-	static NestableJoinColumnAnnotation createJoinTableJoinColumn(JavaResourceNode parent, Member member, int index) {
-		return new SourceJoinColumnAnnotation(parent, member, buildJoinTableAnnotationAdapter(index));
-	}
-
-	private static IndexedDeclarationAnnotationAdapter buildJoinTableAnnotationAdapter(int index) {
-		return new NestedIndexedDeclarationAnnotationAdapter(SourceJoinTableAnnotation.DECLARATION_ANNOTATION_ADAPTER, JPA.JOIN_TABLE__JOIN_COLUMNS, index, JPA.JOIN_COLUMN);
-	}
-
-	static NestableJoinColumnAnnotation createJoinTableInverseJoinColumn(JavaResourceNode parent, Member member, int index) {
-		return new SourceJoinColumnAnnotation(parent, member, buildJoinTableInverseAnnotationAdapter(index));
-	}
-
-	private static IndexedDeclarationAnnotationAdapter buildJoinTableInverseAnnotationAdapter(int index) {
-		return new NestedIndexedDeclarationAnnotationAdapter(SourceJoinTableAnnotation.DECLARATION_ANNOTATION_ADAPTER, JPA.JOIN_TABLE__INVERSE_JOIN_COLUMNS, index, JPA.JOIN_COLUMN);
-	}
-
-
 	static NestableJoinColumnAnnotation createAssociationOverrideJoinColumn(DeclarationAnnotationAdapter associationOverrideAdapter, JavaResourceNode parent, Member member, int index) {
 		return new SourceJoinColumnAnnotation(parent, member, buildAssociationOverrideAnnotationAdapter(associationOverrideAdapter, index));
 	}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceJoinTableAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceJoinTableAnnotation.java
index 11dabba..56822b9 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceJoinTableAnnotation.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceJoinTableAnnotation.java
@@ -14,16 +14,19 @@
 
 import org.eclipse.jdt.core.dom.CompilationUnit;
 import org.eclipse.jpt.core.internal.utility.jdt.ConversionDeclarationAnnotationElementAdapter;
+import org.eclipse.jpt.core.internal.utility.jdt.NestedIndexedDeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.internal.utility.jdt.SimpleDeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.resource.java.AnnotationContainer;
 import org.eclipse.jpt.core.resource.java.JPA;
 import org.eclipse.jpt.core.resource.java.JavaResourceNode;
 import org.eclipse.jpt.core.resource.java.JoinColumnAnnotation;
 import org.eclipse.jpt.core.resource.java.JoinTableAnnotation;
+import org.eclipse.jpt.core.resource.java.NestableAnnotation;
 import org.eclipse.jpt.core.resource.java.NestableJoinColumnAnnotation;
-import org.eclipse.jpt.core.resource.java.NestableUniqueConstraintAnnotation;
+import org.eclipse.jpt.core.resource.java.NestableJoinTableAnnotation;
 import org.eclipse.jpt.core.utility.jdt.DeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.utility.jdt.DeclarationAnnotationElementAdapter;
+import org.eclipse.jpt.core.utility.jdt.IndexedDeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.utility.jdt.Member;
 import org.eclipse.jpt.utility.internal.CollectionTools;
 import org.eclipse.jpt.utility.internal.StringTools;
@@ -32,17 +35,12 @@
 /**
  * javax.persistence.JoinTable
  */
-public final class SourceJoinTableAnnotation
+public class SourceJoinTableAnnotation
 	extends SourceBaseTableAnnotation
-	implements JoinTableAnnotation
+	implements NestableJoinTableAnnotation
 {
 	public static final DeclarationAnnotationAdapter DECLARATION_ANNOTATION_ADAPTER = new SimpleDeclarationAnnotationAdapter(JoinTableAnnotation.ANNOTATION_NAME);
 
-	private static final DeclarationAnnotationElementAdapter<String> NAME_ADAPTER = ConversionDeclarationAnnotationElementAdapter.forStrings(DECLARATION_ANNOTATION_ADAPTER, JPA.JOIN_TABLE__NAME);
-
-	private static final DeclarationAnnotationElementAdapter<String> SCHEMA_ADAPTER = ConversionDeclarationAnnotationElementAdapter.forStrings(DECLARATION_ANNOTATION_ADAPTER, JPA.JOIN_TABLE__SCHEMA);
-
-	private static final DeclarationAnnotationElementAdapter<String> CATALOG_ADAPTER = ConversionDeclarationAnnotationElementAdapter.forStrings(DECLARATION_ANNOTATION_ADAPTER, JPA.JOIN_TABLE__CATALOG);
 
 	private final Vector<NestableJoinColumnAnnotation> joinColumns = new Vector<NestableJoinColumnAnnotation>();
 	private final JoinColumnsAnnotationContainer joinColumnsContainer = new JoinColumnsAnnotationContainer();
@@ -52,7 +50,11 @@
 
 
 	public SourceJoinTableAnnotation(JavaResourceNode parent, Member member) {
-		super(parent, member, DECLARATION_ANNOTATION_ADAPTER);
+		this(parent, member, DECLARATION_ANNOTATION_ADAPTER);
+	}
+
+	public SourceJoinTableAnnotation(JavaResourceNode parent, Member member, DeclarationAnnotationAdapter daa) {
+		super(parent, member, daa);
 	}
 
 	public String getAnnotationName() {
@@ -78,20 +80,17 @@
 
 	@Override
 	DeclarationAnnotationElementAdapter<String> getNameAdapter(DeclarationAnnotationAdapter declarationAnnotationAdapter) {
-		// ignore the daa passed in, @JoinTable is never nested
-		return NAME_ADAPTER;
+		return ConversionDeclarationAnnotationElementAdapter.forStrings(declarationAnnotationAdapter, JPA.JOIN_TABLE__NAME);
 	}
 
 	@Override
 	DeclarationAnnotationElementAdapter<String> getSchemaAdapter(DeclarationAnnotationAdapter declarationAnnotationAdapter) {
-		// ignore the daa passed in, @JoinTable is never nested
-		return SCHEMA_ADAPTER;
+		return ConversionDeclarationAnnotationElementAdapter.forStrings(declarationAnnotationAdapter, JPA.JOIN_TABLE__SCHEMA);
 	}
 
 	@Override
 	DeclarationAnnotationElementAdapter<String> getCatalogAdapter(DeclarationAnnotationAdapter declarationAnnotationAdapter) {
-		// ignore the daa passed in, @JoinTable is never nested
-		return CATALOG_ADAPTER;
+		return ConversionDeclarationAnnotationElementAdapter.forStrings(declarationAnnotationAdapter, JPA.JOIN_TABLE__CATALOG);
 	}
 
 	@Override
@@ -99,12 +98,6 @@
 		return JPA.JOIN_TABLE__UNIQUE_CONSTRAINTS;
 	}
 
-	@Override
-	NestableUniqueConstraintAnnotation buildUniqueConstraint(int index) {
-		return SourceUniqueConstraintAnnotation.createJoinTableUniqueConstraint(this, this.member, index);
-	}
-
-
 	// ********** JoinTableAnnotation implementation **********
 
 	// ***** join columns
@@ -139,7 +132,11 @@
 	}
 
 	private NestableJoinColumnAnnotation buildJoinColumn(int index) {
-		return SourceJoinColumnAnnotation.createJoinTableJoinColumn(this, this.member, index);
+		return new SourceJoinColumnAnnotation(this, this.member, buildJoinColumnAnnotationAdapter(index));
+	}
+
+	private IndexedDeclarationAnnotationAdapter buildJoinColumnAnnotationAdapter(int index) {
+		return new NestedIndexedDeclarationAnnotationAdapter(this.daa, JPA.JOIN_TABLE__JOIN_COLUMNS, index, JPA.JOIN_COLUMN);
 	}
 
 	void joinColumnAdded(int index, NestableJoinColumnAnnotation joinColumn) {
@@ -206,7 +203,11 @@
 	}
 
 	private NestableJoinColumnAnnotation buildInverseJoinColumn(int index) {
-		return SourceJoinColumnAnnotation.createJoinTableInverseJoinColumn(this, this.member, index);
+		return new SourceJoinColumnAnnotation(this, this.member, buildInverseJoinColumnAnnotationAdapter(index));
+	}
+
+	private IndexedDeclarationAnnotationAdapter buildInverseJoinColumnAnnotationAdapter(int index) {
+		return new NestedIndexedDeclarationAnnotationAdapter(this.daa, JPA.JOIN_TABLE__INVERSE_JOIN_COLUMNS, index, JPA.JOIN_COLUMN);
 	}
 
 	void inverseJoinColumnAdded(int index, NestableJoinColumnAnnotation joinColumn) {
@@ -241,6 +242,30 @@
 		return this.addInverseJoinColumnInternal();
 	}
 
+	// ********** NestableAnnotation implementation **********
+
+	@Override
+	public void initializeFrom(NestableAnnotation oldAnnotation) {
+		super.initializeFrom(oldAnnotation);
+		JoinTableAnnotation oldJoinTable = (JoinTableAnnotation) oldAnnotation;
+		for (JoinColumnAnnotation oldJoinColumn : CollectionTools.iterable(oldJoinTable.joinColumns())) {
+			NestableJoinColumnAnnotation newJoinColumn = this.addJoinColumn(oldJoinTable.indexOfJoinColumn(oldJoinColumn));
+			newJoinColumn.initializeFrom((NestableAnnotation) oldJoinColumn);
+		}
+		for (JoinColumnAnnotation oldInverseJoinColumn : CollectionTools.iterable(oldJoinTable.inverseJoinColumns())) {
+			NestableJoinColumnAnnotation newInverseJoinColumn = this.addInverseJoinColumn(oldJoinTable.indexOfInverseJoinColumn(oldInverseJoinColumn));
+			newInverseJoinColumn.initializeFrom((NestableAnnotation) oldInverseJoinColumn);
+		}
+	}
+
+	public void moveAnnotation(int newIndex) {
+		// the only place where a join table annotation is nested is in an
+		// association override; and that only nests a single join table, not an array
+		// of join tables; so #moveAnnotation(int) is never called
+		// TODO maybe NestableAnnotation should be split up;
+		// moving this method to something like IndexableAnnotation
+		throw new UnsupportedOperationException();
+	}
 
 	// ********** annotation containers **********
 
@@ -263,7 +288,6 @@
 		public String toString() {
 			return StringTools.buildToStringFor(this);
 		}
-
 	}
 
 
@@ -308,7 +332,6 @@
 		public void nestedAnnotationRemoved(int index, NestableJoinColumnAnnotation nestedAnnotation) {
 			SourceJoinTableAnnotation.this.joinColumnRemoved(index, nestedAnnotation);
 		}
-
 	}
 
 
@@ -353,7 +376,6 @@
 		public void nestedAnnotationRemoved(int index, NestableJoinColumnAnnotation nestedAnnotation) {
 			SourceJoinTableAnnotation.this.inverseJoinColumnRemoved(index, nestedAnnotation);
 		}
-
 	}
 
 }
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceSecondaryTableAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceSecondaryTableAnnotation.java
index e9dbb2f..ada1107 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceSecondaryTableAnnotation.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceSecondaryTableAnnotation.java
@@ -24,10 +24,8 @@
 import org.eclipse.jpt.core.resource.java.NestableAnnotation;
 import org.eclipse.jpt.core.resource.java.NestablePrimaryKeyJoinColumnAnnotation;
 import org.eclipse.jpt.core.resource.java.NestableSecondaryTableAnnotation;
-import org.eclipse.jpt.core.resource.java.NestableUniqueConstraintAnnotation;
 import org.eclipse.jpt.core.resource.java.PrimaryKeyJoinColumnAnnotation;
 import org.eclipse.jpt.core.resource.java.SecondaryTableAnnotation;
-import org.eclipse.jpt.core.resource.java.UniqueConstraintAnnotation;
 import org.eclipse.jpt.core.utility.jdt.AnnotationAdapter;
 import org.eclipse.jpt.core.utility.jdt.DeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.utility.jdt.DeclarationAnnotationElementAdapter;
@@ -94,11 +92,6 @@
 		return JPA.SECONDARY_TABLE__UNIQUE_CONSTRAINTS;
 	}
 
-	@Override
-	NestableUniqueConstraintAnnotation buildUniqueConstraint(int index) {
-		return SourceUniqueConstraintAnnotation.createSecondaryTableUniqueConstraint(this, this.member, this.daa, index);
-	}
-
 
 	// ************* SecondaryTable implementation *******************
 
@@ -176,15 +169,10 @@
 		return (IndexedAnnotationAdapter) this.annotationAdapter;
 	}
 
+	@Override
 	public void initializeFrom(NestableAnnotation oldAnnotation) {
+		super.initializeFrom(oldAnnotation);
 		SecondaryTableAnnotation oldTable = (SecondaryTableAnnotation) oldAnnotation;
-		this.setName(oldTable.getName());
-		this.setSchema(oldTable.getSchema());
-		this.setCatalog(oldTable.getCatalog());
-		for (UniqueConstraintAnnotation oldUniqueConstraint : CollectionTools.iterable(oldTable.uniqueConstraints())) {
-			NestableUniqueConstraintAnnotation newUniqueConstraint = this.addUniqueConstraint(oldTable.indexOfUniqueConstraint(oldUniqueConstraint));
-			newUniqueConstraint.initializeFrom((NestableAnnotation) oldUniqueConstraint);
-		}
 		for (PrimaryKeyJoinColumnAnnotation oldPkJoinColumn : CollectionTools.iterable(oldTable.pkJoinColumns())) {
 			NestablePrimaryKeyJoinColumnAnnotation newPkJoinColumn = this.addPkJoinColumn(oldTable.indexOfPkJoinColumn(oldPkJoinColumn));
 			newPkJoinColumn.initializeFrom((NestableAnnotation) oldPkJoinColumn);
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceTableAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceTableAnnotation.java
index 0ac734b..546ebe3 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceTableAnnotation.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceTableAnnotation.java
@@ -13,7 +13,6 @@
 import org.eclipse.jpt.core.internal.utility.jdt.SimpleDeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.resource.java.JPA;
 import org.eclipse.jpt.core.resource.java.JavaResourceNode;
-import org.eclipse.jpt.core.resource.java.NestableUniqueConstraintAnnotation;
 import org.eclipse.jpt.core.resource.java.TableAnnotation;
 import org.eclipse.jpt.core.utility.jdt.DeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.utility.jdt.DeclarationAnnotationElementAdapter;
@@ -69,9 +68,4 @@
 		return JPA.TABLE__UNIQUE_CONSTRAINTS;
 	}
 
-	@Override
-	NestableUniqueConstraintAnnotation buildUniqueConstraint(int index) {
-		return SourceUniqueConstraintAnnotation.createTableUniqueConstraint(this, this.member, index);
-	}
-
 }
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceTableGeneratorAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceTableGeneratorAnnotation.java
index 096104f..328cdf6 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceTableGeneratorAnnotation.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceTableGeneratorAnnotation.java
@@ -13,6 +13,7 @@
 import java.util.Vector;
 
 import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jpt.core.internal.utility.jdt.NestedIndexedDeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.internal.utility.jdt.SimpleDeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.resource.java.AnnotationContainer;
 import org.eclipse.jpt.core.resource.java.JPA;
@@ -24,6 +25,7 @@
 import org.eclipse.jpt.core.utility.jdt.AnnotationElementAdapter;
 import org.eclipse.jpt.core.utility.jdt.DeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.utility.jdt.DeclarationAnnotationElementAdapter;
+import org.eclipse.jpt.core.utility.jdt.IndexedDeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.utility.jdt.Member;
 import org.eclipse.jpt.utility.internal.CollectionTools;
 import org.eclipse.jpt.utility.internal.StringTools;
@@ -323,9 +325,13 @@
 		this.uniqueConstraints.add(uniqueConstraint);
 		return uniqueConstraint;
 	}
+	
+	NestableUniqueConstraintAnnotation buildUniqueConstraint(int index) {
+		return new SourceUniqueConstraintAnnotation(this, this.member, buildUniqueConstraintAnnotationAdapter(index));
+	}
 
-	private NestableUniqueConstraintAnnotation buildUniqueConstraint(int index) {
-		return SourceUniqueConstraintAnnotation.createTableGeneratorUniqueConstraint(this, this.member, index);
+	IndexedDeclarationAnnotationAdapter buildUniqueConstraintAnnotationAdapter(int index) {
+		return new NestedIndexedDeclarationAnnotationAdapter(this.daa, JPA.TABLE_GENERATOR__UNIQUE_CONSTRAINTS, index, JPA.UNIQUE_CONSTRAINT);
 	}
 
 	void uniqueConstraintAdded(int index, NestableUniqueConstraintAnnotation constraint) {
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceUniqueConstraintAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceUniqueConstraintAnnotation.java
index 3056445..334eb0b 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceUniqueConstraintAnnotation.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/internal/resource/java/source/SourceUniqueConstraintAnnotation.java
@@ -17,7 +17,6 @@
 import org.eclipse.jpt.core.internal.utility.jdt.AnnotationStringArrayExpressionConverter;
 import org.eclipse.jpt.core.internal.utility.jdt.ConversionDeclarationAnnotationElementAdapter;
 import org.eclipse.jpt.core.internal.utility.jdt.MemberIndexedAnnotationAdapter;
-import org.eclipse.jpt.core.internal.utility.jdt.NestedIndexedDeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.internal.utility.jdt.ShortCircuitArrayAnnotationElementAdapter;
 import org.eclipse.jpt.core.internal.utility.jdt.SimpleDeclarationAnnotationAdapter;
 import org.eclipse.jpt.core.resource.java.JPA;
@@ -154,39 +153,4 @@
 		this.getIndexedAnnotationAdapter().moveAnnotation(newIndex);
 	}
 
-
-	// ********** static methods **********
-
-	static NestableUniqueConstraintAnnotation createSecondaryTableUniqueConstraint(JavaResourceNode parent, Member member, DeclarationAnnotationAdapter declarationAnnotationAdapter, int index) {
-		return new SourceUniqueConstraintAnnotation(parent, member, buildSecondaryTableUniqueConstraintAnnotationAdapter(declarationAnnotationAdapter, index));
-	}
-
-	private static IndexedDeclarationAnnotationAdapter buildSecondaryTableUniqueConstraintAnnotationAdapter(DeclarationAnnotationAdapter declarationAnnotationAdapter, int index) {
-		return new NestedIndexedDeclarationAnnotationAdapter(declarationAnnotationAdapter, JPA.SECONDARY_TABLE__UNIQUE_CONSTRAINTS, index, JPA.UNIQUE_CONSTRAINT);
-	}
-
-	static NestableUniqueConstraintAnnotation createJoinTableUniqueConstraint(JavaResourceNode parent, Member member, int index) {
-		return new SourceUniqueConstraintAnnotation(parent, member, buildJoinTableUniqueConstraintAnnotationAdapter(index));
-	}
-
-	private static IndexedDeclarationAnnotationAdapter buildJoinTableUniqueConstraintAnnotationAdapter(int index) {
-		return new NestedIndexedDeclarationAnnotationAdapter(SourceJoinTableAnnotation.DECLARATION_ANNOTATION_ADAPTER, JPA.JOIN_TABLE__UNIQUE_CONSTRAINTS, index, JPA.UNIQUE_CONSTRAINT);
-	}
-
-	static NestableUniqueConstraintAnnotation createTableUniqueConstraint(JavaResourceNode parent, Member member, int index) {
-		return new SourceUniqueConstraintAnnotation(parent, member, buildTableUniqueConstraintAnnotationAdapter(index));
-	}
-
-	private static IndexedDeclarationAnnotationAdapter buildTableUniqueConstraintAnnotationAdapter(int index) {
-		return new NestedIndexedDeclarationAnnotationAdapter(SourceTableAnnotation.DECLARATION_ANNOTATION_ADAPTER, JPA.TABLE__UNIQUE_CONSTRAINTS, index, JPA.UNIQUE_CONSTRAINT);
-	}
-
-	static NestableUniqueConstraintAnnotation createTableGeneratorUniqueConstraint(JavaResourceNode parent, Member member, int index) {
-		return new SourceUniqueConstraintAnnotation(parent, member, buildTableGeneratorUniqueConstraintAnnotationAdapter(index));
-	}
-
-	private static IndexedDeclarationAnnotationAdapter buildTableGeneratorUniqueConstraintAnnotationAdapter(int index) {
-		return new NestedIndexedDeclarationAnnotationAdapter(SourceTableGeneratorAnnotation.DECLARATION_ANNOTATION_ADAPTER, JPA.TABLE_GENERATOR__UNIQUE_CONSTRAINTS, index, JPA.UNIQUE_CONSTRAINT);
-	}
-
 }
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/NestableJoinTableAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/NestableJoinTableAnnotation.java
new file mode 100644
index 0000000..025aee5
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt/core/resource/java/NestableJoinTableAnnotation.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.core.resource.java;
+
+
+/**
+ * Corresponds to the JPA annotation
+ * javax.persistence.JoinTable
+ * 
+ * Provisional API: This interface is part of an interim API that is still
+ * under development and expected to change significantly before reaching
+ * stability. It is available at this early stage to solicit feedback from
+ * pioneering adopters on the understanding that any code that uses this API
+ * will almost certainly be broken (repeatedly) as the API evolves.
+ */
+public interface NestableJoinTableAnnotation
+	extends NestableAnnotation, JoinTableAnnotation
+{
+	// combine two interfaces
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/platform/Generic2_0JpaAnnotationDefinitionProvider.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/platform/Generic2_0JpaAnnotationDefinitionProvider.java
index aff597d..a388ca1 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/platform/Generic2_0JpaAnnotationDefinitionProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/platform/Generic2_0JpaAnnotationDefinitionProvider.java
@@ -10,18 +10,58 @@
 package org.eclipse.jpt2_0.core.internal.platform;
 
 import java.util.List;
-
 import org.eclipse.jpt.core.JpaAnnotationDefinitionProvider;
-import org.eclipse.jpt.core.internal.platform.GenericJpaAnnotationDefinitionProvider;
+import org.eclipse.jpt.core.internal.platform.AbstractJpaAnnotationDefintionProvider;
+import org.eclipse.jpt.core.internal.resource.java.AttributeOverrideAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.AttributeOverridesAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.BasicAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.ColumnAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.DiscriminatorColumnAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.DiscriminatorValueAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.EmbeddableAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.EmbeddedAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.EmbeddedIdAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.EntityAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.EnumeratedAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.GeneratedValueAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.IdAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.IdClassAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.InheritanceAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.JoinColumnAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.JoinColumnsAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.JoinTableAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.LobAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.ManyToManyAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.ManyToOneAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.MapKeyAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.MappedSuperclassAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.NamedNativeQueriesAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.NamedNativeQueryAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.NamedQueriesAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.NamedQueryAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.OneToManyAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.OneToOneAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.OrderByAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.PrimaryKeyJoinColumnAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.PrimaryKeyJoinColumnsAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.SecondaryTableAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.SecondaryTablesAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.TableAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.TableGeneratorAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.TemporalAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.TransientAnnotationDefinition;
+import org.eclipse.jpt.core.internal.resource.java.VersionAnnotationDefinition;
 import org.eclipse.jpt.core.resource.java.AnnotationDefinition;
 import org.eclipse.jpt2_0.core.internal.resource.java.AccessAnnotationDefinition;
+import org.eclipse.jpt2_0.core.internal.resource.java.AssociationOverride2_0AnnotationDefinition;
+import org.eclipse.jpt2_0.core.internal.resource.java.AssociationOverrides2_0AnnotationDefinition;
 import org.eclipse.jpt2_0.core.internal.resource.java.SequenceGenerator2_0AnnotationDefinition;
 
 /**
- * Provides annotations only for JPA 2.0
+ * Provides annotations for JPA 2.0, including those in JPA 1.0
  */
 public class Generic2_0JpaAnnotationDefinitionProvider
-	extends GenericJpaAnnotationDefinitionProvider
+	extends AbstractJpaAnnotationDefintionProvider
 {
 	// singleton
 	private static final JpaAnnotationDefinitionProvider INSTANCE = new Generic2_0JpaAnnotationDefinitionProvider();
@@ -42,31 +82,70 @@
 
 	@Override
 	protected void addTypeMappingAnnotationDefinitionsTo(List<AnnotationDefinition> definitions) {
-		super.addTypeMappingAnnotationDefinitionsTo(definitions);
+		definitions.add(EmbeddableAnnotationDefinition.instance());
+		definitions.add(EntityAnnotationDefinition.instance());
+		definitions.add(MappedSuperclassAnnotationDefinition.instance());
 	}
 	
 	@Override
 	protected void addTypeSupportingAnnotationDefinitionsTo(List<AnnotationDefinition> definitions) {
-		super.addTypeSupportingAnnotationDefinitionsTo(definitions);
-
 		definitions.add(AccessAnnotationDefinition.instance());
+		definitions.add(AssociationOverride2_0AnnotationDefinition.instance());
+		definitions.add(AssociationOverrides2_0AnnotationDefinition.instance());
+		definitions.add(AttributeOverrideAnnotationDefinition.instance());
+		definitions.add(AttributeOverridesAnnotationDefinition.instance());
+		definitions.add(DiscriminatorColumnAnnotationDefinition.instance());
+		definitions.add(DiscriminatorValueAnnotationDefinition.instance());
+		definitions.add(IdClassAnnotationDefinition.instance());
+		definitions.add(InheritanceAnnotationDefinition.instance());
+		definitions.add(NamedQueryAnnotationDefinition.instance());
+		definitions.add(NamedQueriesAnnotationDefinition.instance());
+		definitions.add(NamedNativeQueryAnnotationDefinition.instance());
+		definitions.add(NamedNativeQueriesAnnotationDefinition.instance());
+		definitions.add(PrimaryKeyJoinColumnAnnotationDefinition.instance());
+		definitions.add(PrimaryKeyJoinColumnsAnnotationDefinition.instance());
+		definitions.add(SecondaryTableAnnotationDefinition.instance());
+		definitions.add(SecondaryTablesAnnotationDefinition.instance());
+		definitions.add(SequenceGenerator2_0AnnotationDefinition.instance());
+		definitions.add(TableAnnotationDefinition.instance());
+		definitions.add(TableGeneratorAnnotationDefinition.instance());		
 	}
 
 	@Override
 	protected void addAttributeMappingAnnotationDefinitionsTo(List<AnnotationDefinition> definitions) {
-		super.addAttributeMappingAnnotationDefinitionsTo(definitions);
+		definitions.add(BasicAnnotationDefinition.instance());
+		definitions.add(EmbeddedAnnotationDefinition.instance());
+		definitions.add(EmbeddedIdAnnotationDefinition.instance());
+		definitions.add(IdAnnotationDefinition.instance());
+		definitions.add(ManyToManyAnnotationDefinition.instance());
+		definitions.add(ManyToOneAnnotationDefinition.instance());
+		definitions.add(OneToManyAnnotationDefinition.instance());
+		definitions.add(OneToOneAnnotationDefinition.instance());
+		definitions.add(TransientAnnotationDefinition.instance());
+		definitions.add(VersionAnnotationDefinition.instance());
 	}
 	
 	@Override
 	protected void addAttributeSupportingAnnotationDefinitionsTo(List<AnnotationDefinition> definitions) {
-		super.addAttributeSupportingAnnotationDefinitionsTo(definitions);
-		
 		definitions.add(AccessAnnotationDefinition.instance());
-	}
-
-	@Override
-	protected  AnnotationDefinition sequenceGeneratorAnnotationDefinition() {
-		return SequenceGenerator2_0AnnotationDefinition.instance();
+		definitions.add(AssociationOverride2_0AnnotationDefinition.instance());
+		definitions.add(AssociationOverrides2_0AnnotationDefinition.instance());
+		definitions.add(AttributeOverrideAnnotationDefinition.instance());
+		definitions.add(AttributeOverridesAnnotationDefinition.instance());
+		definitions.add(ColumnAnnotationDefinition.instance());
+		definitions.add(EnumeratedAnnotationDefinition.instance());
+		definitions.add(GeneratedValueAnnotationDefinition.instance());
+		definitions.add(JoinColumnAnnotationDefinition.instance());
+		definitions.add(JoinColumnsAnnotationDefinition.instance());
+		definitions.add(JoinTableAnnotationDefinition.instance());
+		definitions.add(LobAnnotationDefinition.instance());
+		definitions.add(MapKeyAnnotationDefinition.instance());
+		definitions.add(OrderByAnnotationDefinition.instance());
+		definitions.add(PrimaryKeyJoinColumnAnnotationDefinition.instance());
+		definitions.add(PrimaryKeyJoinColumnsAnnotationDefinition.instance());
+		definitions.add(SequenceGenerator2_0AnnotationDefinition.instance());
+		definitions.add(TableGeneratorAnnotationDefinition.instance());
+		definitions.add(TemporalAnnotationDefinition.instance());
 	}
 
 }
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/AssociationOverride2_0AnnotationDefinition.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/AssociationOverride2_0AnnotationDefinition.java
new file mode 100644
index 0000000..a43c39f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/AssociationOverride2_0AnnotationDefinition.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.jpt2_0.core.internal.resource.java;
+
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jpt.core.resource.java.Annotation;
+import org.eclipse.jpt.core.resource.java.AnnotationDefinition;
+import org.eclipse.jpt.core.resource.java.AssociationOverrideAnnotation;
+import org.eclipse.jpt.core.resource.java.JavaResourcePersistentMember;
+import org.eclipse.jpt.core.utility.jdt.Member;
+import org.eclipse.jpt2_0.core.internal.resource.java.binary.BinaryAssociationOverride2_0Annotation;
+import org.eclipse.jpt2_0.core.internal.resource.java.source.SourceAssociationOverride2_0Annotation;
+
+/**
+ * javax.persistence.AssociationOverride
+ */
+public class AssociationOverride2_0AnnotationDefinition
+	implements AnnotationDefinition
+{
+	// singleton
+	private static final AnnotationDefinition INSTANCE = new AssociationOverride2_0AnnotationDefinition();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static AnnotationDefinition instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure single instance.
+	 */
+	private AssociationOverride2_0AnnotationDefinition() {
+		super();
+	}
+
+	public Annotation buildAnnotation(JavaResourcePersistentMember parent, Member member) {
+		return SourceAssociationOverride2_0Annotation.createAssociationOverride(parent, member);
+	}
+
+	public Annotation buildNullAnnotation(JavaResourcePersistentMember parent) {
+		throw new UnsupportedOperationException();
+	}
+
+	public Annotation buildAnnotation(JavaResourcePersistentMember parent, IAnnotation jdtAnnotation) {
+		return new BinaryAssociationOverride2_0Annotation(parent, jdtAnnotation);
+	}
+
+	public String getAnnotationName() {
+		return AssociationOverrideAnnotation.ANNOTATION_NAME;
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/AssociationOverrides2_0AnnotationDefinition.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/AssociationOverrides2_0AnnotationDefinition.java
new file mode 100644
index 0000000..abbce22
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/AssociationOverrides2_0AnnotationDefinition.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.jpt2_0.core.internal.resource.java;
+
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jpt.core.resource.java.Annotation;
+import org.eclipse.jpt.core.resource.java.AnnotationDefinition;
+import org.eclipse.jpt.core.resource.java.AssociationOverridesAnnotation;
+import org.eclipse.jpt.core.resource.java.JavaResourcePersistentMember;
+import org.eclipse.jpt.core.utility.jdt.Member;
+import org.eclipse.jpt2_0.core.internal.resource.java.binary.BinaryAssociationOverrides2_0Annotation;
+import org.eclipse.jpt2_0.core.internal.resource.java.source.SourceAssociationOverrides2_0Annotation;
+
+/**
+ * javax.persistence.AssociationOverrides
+ */
+public class AssociationOverrides2_0AnnotationDefinition
+	implements AnnotationDefinition
+{
+	// singleton
+	private static final AnnotationDefinition INSTANCE = new AssociationOverrides2_0AnnotationDefinition();
+
+	/**
+	 * Return the singleton.
+	 */
+	public static AnnotationDefinition instance() {
+		return INSTANCE;
+	}
+
+	/**
+	 * Ensure single instance.
+	 */
+	private AssociationOverrides2_0AnnotationDefinition() {
+		super();
+	}
+
+	public AssociationOverridesAnnotation buildAnnotation(JavaResourcePersistentMember parent, Member member) {
+		return new SourceAssociationOverrides2_0Annotation(parent, member);
+	}
+
+	public AssociationOverridesAnnotation buildNullAnnotation(JavaResourcePersistentMember parent) {
+		throw new UnsupportedOperationException();
+	}
+
+	public Annotation buildAnnotation(JavaResourcePersistentMember parent, IAnnotation jdtAnnotation) {
+		return new BinaryAssociationOverrides2_0Annotation(parent, jdtAnnotation);
+	}
+
+	public String getAnnotationName() {
+		return AssociationOverridesAnnotation.ANNOTATION_NAME;
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/NullAssociationOverrideJoinTableAnnotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/NullAssociationOverrideJoinTableAnnotation.java
new file mode 100644
index 0000000..35dc2c8
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/NullAssociationOverrideJoinTableAnnotation.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.jpt2_0.core.internal.resource.java;
+
+import org.eclipse.jpt.core.internal.resource.java.NullJoinTableAnnotation;
+import org.eclipse.jpt.core.resource.java.JoinTableAnnotation;
+import org.eclipse.jpt2_0.core.resource.java.AssociationOverride2_0Annotation;
+
+/**
+ * javax.persistence.Column
+ */
+public class NullAssociationOverrideJoinTableAnnotation
+	extends NullJoinTableAnnotation
+{
+	public NullAssociationOverrideJoinTableAnnotation(AssociationOverride2_0Annotation parent) {
+		super(parent);
+	}
+
+	private AssociationOverride2_0Annotation getAssociationOverride2_0Annotation() {
+		return (AssociationOverride2_0Annotation) this.parent;
+	}
+
+	@Override
+	protected JoinTableAnnotation buildAnnotation() {
+		return this.getAssociationOverride2_0Annotation().addJoinTable();
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/binary/BinaryAssociationOverride2_0Annotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/binary/BinaryAssociationOverride2_0Annotation.java
new file mode 100644
index 0000000..45da99a
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/binary/BinaryAssociationOverride2_0Annotation.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+* Copyright (c) 2009 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.jpt2_0.core.internal.resource.java.binary;
+
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jpt.core.internal.resource.java.NullJoinTableAnnotation;
+import org.eclipse.jpt.core.internal.resource.java.binary.BinaryAssociationOverrideAnnotation;
+import org.eclipse.jpt.core.internal.resource.java.binary.BinaryJoinTableAnnotation;
+import org.eclipse.jpt.core.resource.java.JavaResourceNode;
+import org.eclipse.jpt.core.resource.java.JoinTableAnnotation;
+import org.eclipse.jpt2_0.core.resource.java.AssociationOverride2_0Annotation;
+import org.eclipse.jpt2_0.core.resource.java.JPA;
+
+/**
+ *  BinarySequenceGenerator2_0Annotation
+ */
+public final class BinaryAssociationOverride2_0Annotation
+	extends BinaryAssociationOverrideAnnotation
+	implements AssociationOverride2_0Annotation
+{
+	private JoinTableAnnotation joinTable;
+
+	public BinaryAssociationOverride2_0Annotation(JavaResourceNode parent, IAnnotation jdtAnnotation) {
+		super(parent, jdtAnnotation);
+		this.joinTable = this.buildJoinTable();
+	}
+
+	@Override
+	public void update() {
+		super.update();
+		this.updateJoinTable();
+	}
+
+	// ********** AssociationOverride2_0Annotation implementation **********
+
+	// ***** joinTable
+	public JoinTableAnnotation getJoinTable() {
+		return this.joinTable;
+	}
+
+	public JoinTableAnnotation getNonNullJoinTable() {
+		return (this.joinTable != null) ? this.joinTable : new NullJoinTableAnnotation(this);
+	}
+
+	public JoinTableAnnotation addJoinTable() {
+		throw new UnsupportedOperationException();
+	}
+
+	public void removeJoinTable() {
+		throw new UnsupportedOperationException();
+	}
+
+	private JoinTableAnnotation buildJoinTable() {
+		IAnnotation jdtJoinTable = this.getJdtJoinTable();
+		return (jdtJoinTable == null) ? null : this.buildJoinTable(jdtJoinTable);
+	}
+
+	private JoinTableAnnotation buildJoinTable(IAnnotation jdtJoinTable) {
+		return new BinaryJoinTableAnnotation(this, jdtJoinTable);
+	}
+
+	private IAnnotation getJdtJoinTable() {
+		return (IAnnotation) this.getJdtMemberValue(JPA.ASSOCIATION_OVERRIDE__JOIN_TABLE);
+	}
+
+	private void setJoinTable(JoinTableAnnotation column) {
+		JoinTableAnnotation old = this.joinTable;
+		this.joinTable = column;
+		this.firePropertyChanged(JOIN_TABLE_PROPERTY, old, column);
+	}
+
+	// TODO
+	private void updateJoinTable() {
+		throw new UnsupportedOperationException();
+//		IAnnotation jdtJoinTable = this.getJdtJoinTable();
+//		if (jdtJoinTable == null) {
+//			this.setJoinTable(null);
+//		} else {
+//			if (this.column == null) {
+//				this.setJoinTable(this.buildJoinTable(jdtJoinTable));
+//			} else {
+//				this.column.update(jdtJoinTable);
+//			}
+//		}
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/binary/BinaryAssociationOverrides2_0Annotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/binary/BinaryAssociationOverrides2_0Annotation.java
new file mode 100644
index 0000000..0f4bda7
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/binary/BinaryAssociationOverrides2_0Annotation.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.jpt2_0.core.internal.resource.java.binary;
+
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jpt.core.internal.resource.java.binary.BinaryAssociationOverridesAnnotation;
+import org.eclipse.jpt.core.resource.java.JavaResourceNode;
+import org.eclipse.jpt.core.resource.java.NestableAssociationOverrideAnnotation;
+
+/**
+ * javax.persistence.AssociationOverrides
+ */
+public class BinaryAssociationOverrides2_0Annotation
+	extends BinaryAssociationOverridesAnnotation
+{
+
+	public BinaryAssociationOverrides2_0Annotation(JavaResourceNode parent, IAnnotation jdtAnnotation) {
+		super(parent, jdtAnnotation);
+	}
+
+	@Override
+	protected NestableAssociationOverrideAnnotation buildAssociationOverride(Object jdtAssociationOverride) {
+		return new BinaryAssociationOverride2_0Annotation(this, (IAnnotation) jdtAssociationOverride);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/source/SourceAssociationOverride2_0Annotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/source/SourceAssociationOverride2_0Annotation.java
new file mode 100644
index 0000000..dad0c37
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/source/SourceAssociationOverride2_0Annotation.java
@@ -0,0 +1,132 @@
+/*******************************************************************************
+* Copyright (c) 2009 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.jpt2_0.core.internal.resource.java.source;
+
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jpt.core.internal.resource.java.source.SourceAssociationOverrideAnnotation;
+import org.eclipse.jpt.core.internal.resource.java.source.SourceJoinTableAnnotation;
+import org.eclipse.jpt.core.internal.utility.jdt.MemberAnnotationAdapter;
+import org.eclipse.jpt.core.internal.utility.jdt.MemberIndexedAnnotationAdapter;
+import org.eclipse.jpt.core.internal.utility.jdt.NestedDeclarationAnnotationAdapter;
+import org.eclipse.jpt.core.internal.utility.jdt.NestedIndexedDeclarationAnnotationAdapter;
+import org.eclipse.jpt.core.resource.java.JavaResourceNode;
+import org.eclipse.jpt.core.resource.java.JoinTableAnnotation;
+import org.eclipse.jpt.core.resource.java.NestableJoinTableAnnotation;
+import org.eclipse.jpt.core.utility.jdt.AnnotationAdapter;
+import org.eclipse.jpt.core.utility.jdt.DeclarationAnnotationAdapter;
+import org.eclipse.jpt.core.utility.jdt.IndexedAnnotationAdapter;
+import org.eclipse.jpt.core.utility.jdt.IndexedDeclarationAnnotationAdapter;
+import org.eclipse.jpt.core.utility.jdt.Member;
+import org.eclipse.jpt2_0.core.internal.resource.java.NullAssociationOverrideJoinTableAnnotation;
+import org.eclipse.jpt2_0.core.resource.java.AssociationOverride2_0Annotation;
+import org.eclipse.jpt2_0.core.resource.java.JPA;
+
+/**
+ *  SourceSequenceGenerator2_0Annotation
+ */
+public final class SourceAssociationOverride2_0Annotation
+	extends SourceAssociationOverrideAnnotation
+	implements AssociationOverride2_0Annotation
+{
+	private final MemberAnnotationAdapter joinTableAdapter;
+	private NestableJoinTableAnnotation joinTable;
+
+
+	// ********** constructor **********
+	public SourceAssociationOverride2_0Annotation(JavaResourceNode parent, Member member, DeclarationAnnotationAdapter daa, AnnotationAdapter annotationAdapter) {
+		super(parent, member, daa, annotationAdapter);
+		this.joinTableAdapter = new MemberAnnotationAdapter(this.member, buildJoinTableAnnotationAdapter(this.daa));
+	}
+	
+	@Override
+	public void initialize(CompilationUnit astRoot) {
+		super.initialize(astRoot);
+		if (this.joinTableAdapter.getAnnotation(astRoot) != null) {
+			this.joinTable = createJoinTableAnnotation(this, this.member, this.daa);
+			this.joinTable.initialize(astRoot);
+		}
+	}
+
+	@Override
+	public void update(CompilationUnit astRoot) {
+		super.update(astRoot);
+		this.updateJoinTable(astRoot);
+	}
+
+	//************ AssociationOverride2_0Annotation implementation ****************
+
+	// ***** joinTable
+	public JoinTableAnnotation getJoinTable() {
+		return this.joinTable;
+	}
+
+	public NestableJoinTableAnnotation addJoinTable() {
+		NestableJoinTableAnnotation table = createJoinTableAnnotation(this, this.member, this.daa);
+		table.newAnnotation();
+		this.setJoinTable(table);
+		return table;
+	}
+
+	public void removeJoinTable() {
+		this.joinTable.removeAnnotation();
+		setJoinTable(null);
+	}
+
+	private void setJoinTable(NestableJoinTableAnnotation joinTable) {
+		JoinTableAnnotation old = this.joinTable;
+		this.joinTable = joinTable;
+		this.firePropertyChanged(JOIN_TABLE_PROPERTY, old, joinTable);
+	}
+
+	public JoinTableAnnotation getNonNullJoinTable() {
+		return (this.joinTable != null) ? this.joinTable : new NullAssociationOverrideJoinTableAnnotation(this);
+	}
+
+	private void updateJoinTable(CompilationUnit astRoot) {
+		if (this.joinTableAdapter.getAnnotation(astRoot) == null) {
+			this.setJoinTable(null);
+		} else {
+			if (this.joinTable == null) {
+				NestableJoinTableAnnotation table = createJoinTableAnnotation(this, this.member, this.daa);
+				table.initialize(astRoot);
+				this.setJoinTable(table);
+			} else {
+				this.joinTable.update(astRoot);
+			}
+		}
+	}
+	
+	
+	// ********** static methods **********
+
+	public static SourceAssociationOverride2_0Annotation createAssociationOverride(JavaResourceNode parent, Member member) {
+		return new SourceAssociationOverride2_0Annotation(parent, member, DECLARATION_ANNOTATION_ADAPTER, new MemberAnnotationAdapter(member, DECLARATION_ANNOTATION_ADAPTER));
+	}
+
+	static NestableJoinTableAnnotation createJoinTableAnnotation(JavaResourceNode parent, Member member, DeclarationAnnotationAdapter associationOverrideAnnotationAdapter) {
+		return new SourceJoinTableAnnotation(parent, member, buildJoinTableAnnotationAdapter(associationOverrideAnnotationAdapter));
+	}
+
+	static DeclarationAnnotationAdapter buildJoinTableAnnotationAdapter(DeclarationAnnotationAdapter associationOverrideAnnotationAdapter) {
+		return new NestedDeclarationAnnotationAdapter(associationOverrideAnnotationAdapter, JPA.ASSOCIATION_OVERRIDE__JOIN_TABLE, org.eclipse.jpt.core.resource.java.JPA.JOIN_TABLE);
+	}
+
+	
+	static SourceAssociationOverrideAnnotation createNestedAssociationOverride(JavaResourceNode parent, Member member, int index, DeclarationAnnotationAdapter attributeOverridesAdapter) {
+		IndexedDeclarationAnnotationAdapter idaa = buildNestedDeclarationAnnotationAdapter(index, attributeOverridesAdapter);
+		IndexedAnnotationAdapter annotationAdapter = new MemberIndexedAnnotationAdapter(member, idaa);
+		return new SourceAssociationOverride2_0Annotation(parent, member, idaa, annotationAdapter);
+	}
+
+	protected static IndexedDeclarationAnnotationAdapter buildNestedDeclarationAnnotationAdapter(int index, DeclarationAnnotationAdapter attributeOverridesAdapter) {
+		return new NestedIndexedDeclarationAnnotationAdapter(attributeOverridesAdapter, index, org.eclipse.jpt.core.resource.java.JPA.ASSOCIATION_OVERRIDE);
+	}
+
+}
\ No newline at end of file
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/source/SourceAssociationOverrides2_0Annotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/source/SourceAssociationOverrides2_0Annotation.java
new file mode 100644
index 0000000..960d7f1
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/internal/resource/java/source/SourceAssociationOverrides2_0Annotation.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.jpt2_0.core.internal.resource.java.source;
+
+import org.eclipse.jpt.core.internal.resource.java.source.SourceAssociationOverridesAnnotation;
+import org.eclipse.jpt.core.resource.java.AssociationOverridesAnnotation;
+import org.eclipse.jpt.core.resource.java.JavaResourceNode;
+import org.eclipse.jpt.core.resource.java.NestableAssociationOverrideAnnotation;
+import org.eclipse.jpt.core.utility.jdt.Member;
+
+/**
+ * javax.persistence.AssociationOverrides
+ */
+public final class SourceAssociationOverrides2_0Annotation
+	extends SourceAssociationOverridesAnnotation
+	implements AssociationOverridesAnnotation
+{
+
+
+	public SourceAssociationOverrides2_0Annotation(JavaResourceNode parent, Member member) {
+		super(parent, member);
+	}
+
+	@Override
+	protected NestableAssociationOverrideAnnotation buildAssociationOverride(int index) {
+		return SourceAssociationOverride2_0Annotation.createNestedAssociationOverride(this, this.member, index, this.daa);
+	}
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/resource/java/AssociationOverride2_0Annotation.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/resource/java/AssociationOverride2_0Annotation.java
new file mode 100644
index 0000000..2d4631f
--- /dev/null
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/resource/java/AssociationOverride2_0Annotation.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.jpt2_0.core.resource.java;
+
+import org.eclipse.jpt.core.resource.java.AssociationOverrideAnnotation;
+import org.eclipse.jpt.core.resource.java.JoinTableAnnotation;
+
+/**
+ * Corresponds to the JPA 2.0 annotation
+ * javax.persistence.AssociationOverride
+ * 
+ * Provisional API: This interface is part of an interim API that is still
+ * under development and expected to change significantly before reaching
+ * stability. It is available at this early stage to solicit feedback from
+ * pioneering adopters on the understanding that any code that uses this API
+ * will almost certainly be broken (repeatedly) as the API evolves.
+ */
+public interface AssociationOverride2_0Annotation
+	extends AssociationOverrideAnnotation
+{
+	
+	/**
+	 * Corresponds to the 'joinTable' element of the AssociationOverride annotation.
+	 * Return null if the element does not exist in Java.
+	 */
+	JoinTableAnnotation getJoinTable();
+		String JOIN_TABLE_PROPERTY = "joinTable"; //$NON-NLS-1$
+
+	JoinTableAnnotation getNonNullJoinTable();
+
+	/**
+	 * Add the 'joinTable' element to the AssociationOverride annotation.
+	 */
+	JoinTableAnnotation addJoinTable();
+
+	/**
+	 * Remove the 'joinTable' element from the AssociationOverride annotation.
+	 */
+	void removeJoinTable();
+
+}
diff --git a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/resource/java/JPA.java b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/resource/java/JPA.java
index 61798fa..95184b0 100644
--- a/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/resource/java/JPA.java
+++ b/jpa/plugins/org.eclipse.jpt.core/src/org/eclipse/jpt2_0/core/resource/java/JPA.java
@@ -29,7 +29,9 @@
 	// JPA 2.0 annotations
 	String ACCESS = PACKAGE_ + "Access";
 		String ACCESS__VALUE = "value";
-		
+	
+	String ASSOCIATION_OVERRIDE__JOIN_TABLE = "joinTable";
+	
 	String SEQUENCE_GENERATOR__CATALOG = "catalog";
 	String SEQUENCE_GENERATOR__SCHEMA = "schema";
 
diff --git a/jpa/plugins/org.eclipse.jpt.eclipselink.core/src/org/eclipse/jpt/eclipselink/core/internal/EclipseLinkJpaAnnotationDefinitionProvider.java b/jpa/plugins/org.eclipse.jpt.eclipselink.core/src/org/eclipse/jpt/eclipselink/core/internal/EclipseLinkJpaAnnotationDefinitionProvider.java
index 45b6c3c..07ebac7 100644
--- a/jpa/plugins/org.eclipse.jpt.eclipselink.core/src/org/eclipse/jpt/eclipselink/core/internal/EclipseLinkJpaAnnotationDefinitionProvider.java
+++ b/jpa/plugins/org.eclipse.jpt.eclipselink.core/src/org/eclipse/jpt/eclipselink/core/internal/EclipseLinkJpaAnnotationDefinitionProvider.java
@@ -34,8 +34,7 @@
 import org.eclipse.jpt.eclipselink.core.internal.resource.java.WriteTransformerAnnotationDefinition;
 
 /**
- * Provides annotations for 1.0 EclipseLink platform which includes JPA annotations and
- * EclipseLink 1.0 annotations
+ * Provides annotations for 1.0 EclipseLink platform
  */
 public class EclipseLinkJpaAnnotationDefinitionProvider
 	extends AbstractJpaAnnotationDefintionProvider
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/resource/java/AttributeOverrideTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/resource/java/AttributeOverrideTests.java
index 74aa629..2b62b55 100644
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/resource/java/AttributeOverrideTests.java
+++ b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt/core/tests/internal/resource/java/AttributeOverrideTests.java
@@ -136,6 +136,11 @@
 		AttributeOverrideAnnotation attributeOverride = (AttributeOverrideAnnotation) attributeResource.getSupportingAnnotation(JPA.ATTRIBUTE_OVERRIDE);
 		ColumnAnnotation column = attributeOverride.getColumn();
 		assertNull(column);
+		
+		attributeOverride.addColumn();
+		column = attributeOverride.getColumn();
+		assertNotNull(column);
+		assertSourceContains("@AttributeOverride(name = \"" + ATTRIBUTE_OVERRIDE_NAME + "\", column = @Column)", cu);		
 	}
 	
 	public void testRemoveColumn() throws Exception {
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt2_0/core/tests/internal/resource/java/AssociationOverride2_0Tests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt2_0/core/tests/internal/resource/java/AssociationOverride2_0Tests.java
new file mode 100644
index 0000000..0b499a3
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt2_0/core/tests/internal/resource/java/AssociationOverride2_0Tests.java
@@ -0,0 +1,885 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.jpt2_0.core.tests.internal.resource.java;
+
+import java.util.Iterator;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jpt.core.resource.java.AssociationOverrideAnnotation;
+import org.eclipse.jpt.core.resource.java.JPA;
+import org.eclipse.jpt.core.resource.java.JavaResourcePersistentAttribute;
+import org.eclipse.jpt.core.resource.java.JavaResourcePersistentType;
+import org.eclipse.jpt.core.resource.java.JoinColumnAnnotation;
+import org.eclipse.jpt.core.resource.java.JoinTableAnnotation;
+import org.eclipse.jpt.utility.internal.iterators.ArrayIterator;
+import org.eclipse.jpt2_0.core.resource.java.AssociationOverride2_0Annotation;
+
+@SuppressWarnings("nls")
+public class AssociationOverride2_0Tests extends Generic2_0JavaResourceModelTestCase {
+	
+	private static final String ASSOCIATION_OVERRIDE_NAME = "MY_ASSOCIATION_OVERRIDE";
+	private static final String JOIN_TABLE_NAME = "MY_JOIN_TABLE";
+	private static final String CATALOG_NAME = "MY_CATALOG";
+	private static final String SCHEMA_NAME = "MY_SCHEMA";
+	
+	public AssociationOverride2_0Tests(String name) {
+		super(name);
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideOnField() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDE);
+			}
+			@Override
+			public void appendIdFieldAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\")");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideOnType() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDE);
+			}
+			@Override
+			public void appendTypeAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\")");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideWithJoinColumns() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDE, JPA.JOIN_COLUMN);
+			}
+			@Override
+			public void appendIdFieldAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"BAR\"), @JoinColumn})");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideWithJoinTable() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDE, JPA.JOIN_TABLE);
+			}
+			@Override
+			public void appendTypeAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(name = \"" + JOIN_TABLE_NAME + "\"))");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideJoinTableWithCatalog() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDE, JPA.JOIN_TABLE);
+			}
+			@Override
+			public void appendTypeAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(catalog = \"" + CATALOG_NAME + "\"))");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideJoinTableWithSchema() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDE, JPA.JOIN_TABLE);
+			}
+			@Override
+			public void appendTypeAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(schema = \"" + SCHEMA_NAME + "\"))");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideJoinTableWithUniqueConstraints() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDE, JPA.JOIN_TABLE, JPA.UNIQUE_CONSTRAINT);
+			}
+			@Override
+			public void appendTypeAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(uniqueConstraints = {@UniqueConstraint(columnNames = {\"BAR\"}), @UniqueConstraint(columnNames = {\"FOO\"}), @UniqueConstraint(columnNames = {\"BAZ\"})}))");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideJoinTableWithJoinColumns() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDE, JPA.JOIN_TABLE, JPA.JOIN_COLUMN);
+			}
+			@Override
+			public void appendTypeAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = {@JoinColumn(name = \"BAR\"), @JoinColumn}))");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideJoinTableWithInverseJoinColumns() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDE, JPA.JOIN_TABLE, JPA.JOIN_COLUMN);
+			}
+			@Override
+			public void appendTypeAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(inverseJoinColumns = {@JoinColumn(name = \"BAR\"), @JoinColumn}))");
+			}
+		});
+	}
+
+	public void testGetName() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnField();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+
+		assertNotNull(associationOverride);
+		assertEquals(ASSOCIATION_OVERRIDE_NAME, associationOverride.getName());
+	}
+
+	public void testSetName() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnField();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+
+		assertNotNull(associationOverride);
+		assertEquals(ASSOCIATION_OVERRIDE_NAME, associationOverride.getName());
+
+		associationOverride.setName("Foo");
+		assertEquals("Foo", associationOverride.getName());
+		assertSourceContains("@AssociationOverride(name = \"Foo\")", cu);
+	}
+	
+	public void testSetNameNull() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnField();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+
+		assertEquals(ASSOCIATION_OVERRIDE_NAME, associationOverride.getName());
+		
+		associationOverride.setName(null);
+		assertNull(associationOverride.getName());
+		
+		assertSourceDoesNotContain("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\")", cu);
+		assertSourceContains("@AssociationOverride", cu);
+	}
+	
+	
+	public void testJoinColumns() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnField();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		
+		assertEquals(0, associationOverride.joinColumnsSize());
+	}
+	
+	public void testJoinColumns2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnField();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+
+		
+		associationOverride.addJoinColumn(0);
+		associationOverride.addJoinColumn(1);
+				
+		assertEquals(2, associationOverride.joinColumnsSize());
+	}
+	
+	public void testJoinColumns3() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+				
+		assertEquals(2, associationOverride.joinColumnsSize());
+	}
+	
+	public void testAddJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnField();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		
+		associationOverride.addJoinColumn(0).setName("FOO");
+		associationOverride.addJoinColumn(1);
+		associationOverride.addJoinColumn(0).setName("BAR");
+
+		assertEquals("BAR", associationOverride.joinColumnAt(0).getName());
+		assertEquals("FOO", associationOverride.joinColumnAt(1).getName());
+		assertNull(associationOverride.joinColumnAt(2).getName());
+
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"BAR\"),@JoinColumn(name = \"FOO\"), @JoinColumn})", cu);
+	}
+	
+	public void testRemoveJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		associationOverride.addJoinColumn(0).setName("FOO");
+		
+		Iterator<JoinColumnAnnotation> joinColumns = associationOverride.joinColumns();
+		assertEquals("FOO", joinColumns.next().getName());
+		assertEquals("BAR", joinColumns.next().getName());
+		assertNull(joinColumns.next().getName());
+		assertEquals(false, joinColumns.hasNext());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"FOO\"), @JoinColumn(name = \"BAR\"), @JoinColumn})", cu);
+		
+		associationOverride.removeJoinColumn(1);
+		joinColumns = associationOverride.joinColumns();
+		assertEquals("FOO", joinColumns.next().getName());
+		assertNull(joinColumns.next().getName());
+		assertEquals(false, joinColumns.hasNext());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"FOO\"), @JoinColumn})", cu);
+
+		associationOverride.removeJoinColumn(0);
+		joinColumns = associationOverride.joinColumns();
+		assertNull(joinColumns.next().getName());
+		assertEquals(false, joinColumns.hasNext());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = @JoinColumn)", cu);
+
+		
+		associationOverride.setName(null);
+		associationOverride.removeJoinColumn(0);
+		assertSourceDoesNotContain("@AssociationOverride", cu);
+	}
+	
+	public void testMoveJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinColumnAnnotation joinColumn = associationOverride.joinColumnAt(0);
+		joinColumn.setReferencedColumnName("REF_NAME");
+		joinColumn.setUnique(Boolean.FALSE);
+		joinColumn.setNullable(Boolean.FALSE);
+		joinColumn.setInsertable(Boolean.FALSE);
+		joinColumn.setUpdatable(Boolean.FALSE);
+		joinColumn.setColumnDefinition("COLUMN_DEF");
+		joinColumn.setTable("TABLE");
+		associationOverride.addJoinColumn(0).setName("FOO");
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"FOO\"), @JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\"), @JoinColumn})", cu);
+
+		associationOverride.moveJoinColumn(2, 0);
+		assertEquals("BAR", associationOverride.joinColumnAt(0).getName());
+		assertNull(associationOverride.joinColumnAt(1).getName());
+		assertEquals("FOO", associationOverride.joinColumnAt(2).getName());
+		assertEquals(3, associationOverride.joinColumnsSize());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\"), @JoinColumn, @JoinColumn(name = \"FOO\")})", cu);
+	}
+	
+	public void testMoveJoinColumn2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		
+		JoinColumnAnnotation joinColumn = associationOverride.joinColumnAt(0);
+		joinColumn.setReferencedColumnName("REF_NAME");
+		joinColumn.setUnique(Boolean.FALSE);
+		joinColumn.setNullable(Boolean.FALSE);
+		joinColumn.setInsertable(Boolean.FALSE);
+		joinColumn.setUpdatable(Boolean.FALSE);
+		joinColumn.setColumnDefinition("COLUMN_DEF");
+		joinColumn.setTable("TABLE");
+		associationOverride.addJoinColumn(0).setName("FOO");
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"FOO\"), @JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\"), @JoinColumn})", cu);
+
+		associationOverride.moveJoinColumn(0, 2);
+		assertNull(associationOverride.joinColumnAt(0).getName());
+		assertEquals("FOO", associationOverride.joinColumnAt(1).getName());
+		assertEquals("BAR", associationOverride.joinColumnAt(2).getName());
+		assertEquals(3, associationOverride.joinColumnsSize());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn, @JoinColumn(name = \"FOO\"), @JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\")})", cu);
+	}
+	
+	public void testSetJoinColumnName() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+				
+		assertEquals(2, associationOverride.joinColumnsSize());
+		
+		JoinColumnAnnotation joinColumn = associationOverride.joinColumns().next();
+		
+		assertEquals("BAR", joinColumn.getName());
+		
+		joinColumn.setName("foo");
+		assertEquals("foo", joinColumn.getName());
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"foo\"), @JoinColumn})", cu);
+	}
+		
+	public void testGetNullJoinTable() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnType();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation joinTable = associationOverride.getJoinTable();
+		assertNotNull(associationOverride);
+		assertNull(joinTable);
+	}
+	
+	public void testJoinTableGetName() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation joinTable = associationOverride.getJoinTable();
+		assertEquals(JOIN_TABLE_NAME, joinTable.getName());
+	}
+	
+	public void testJoinTableSetName() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation joinTable = associationOverride.getJoinTable();
+		assertEquals(JOIN_TABLE_NAME, joinTable.getName());
+		
+		joinTable.setName("Foo");
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(name = \"Foo\"))", cu);
+		
+		joinTable.setName(null);
+		assertNull(associationOverride.getJoinTable());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\")", cu);
+	}
+	
+	public void testAddJoinTable() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnType();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation joinTable = associationOverride.getJoinTable();
+		assertNull(joinTable);
+		
+		associationOverride.addJoinTable();
+		joinTable = associationOverride.getJoinTable();
+		assertNotNull(joinTable);
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable)", cu);
+	}
+	
+	public void testRemoveJoinTable() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnType();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation joinTable = associationOverride.getJoinTable();
+		assertNull(joinTable);
+	}
+	
+	public void testJoinTableGetCatalog() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithCatalog();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertNotNull(table);
+		assertEquals(CATALOG_NAME, table.getCatalog());
+	}
+
+	public void testJoinTableSetCatalog() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertNotNull(table);
+		assertNull(table.getCatalog());
+
+		table.setCatalog("Foo");
+		assertEquals("Foo", table.getCatalog());
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(name = \"MY_JOIN_TABLE\", catalog = \"Foo\"))", cu);
+	}
+	
+	public void testJoinTableSetCatalogNull() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithCatalog();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertEquals(CATALOG_NAME, table.getCatalog());
+		
+		table.setCatalog(null);
+		assertNull(table.getCatalog());
+		
+		assertSourceDoesNotContain("@JoinTable", cu);
+	}
+	
+	public void testJoinTableGetSchema() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithSchema();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertNotNull(table);
+		assertEquals(SCHEMA_NAME, table.getSchema());
+	}
+
+	public void testJoinTableSetSchema() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertNotNull(table);
+		assertNull(table.getSchema());
+
+		table.setSchema("Foo");
+		assertEquals("Foo", table.getSchema());
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(name = \"MY_JOIN_TABLE\", schema = \"Foo\"))", cu);
+	}
+	
+	public void testJoinTableSetSchemaNull() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithSchema();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertEquals(SCHEMA_NAME, table.getSchema());
+		
+		table.setSchema(null);
+		assertNull(table.getSchema());
+		
+		assertSourceDoesNotContain("@JoinTable", cu);
+	}
+	
+	public void testJoinTableUniqueConstraints() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		
+		assertEquals(0, table.uniqueConstraintsSize());
+	}
+	
+	public void testJoinTableUniqueConstraints2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+
+		
+		table.addUniqueConstraint(0);
+		table.addUniqueConstraint(1);
+		
+		assertEquals(2, table.uniqueConstraintsSize());
+	}
+	
+	public void testJoinTableUniqueConstraints3() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithUniqueConstraints();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+				
+		assertEquals(3, table.uniqueConstraintsSize());
+	}
+	
+	public void testJoinTableAddUniqueConstraint() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		
+		table.addUniqueConstraint(0).addColumnName("FOO");
+		table.addUniqueConstraint(1);
+		table.addUniqueConstraint(0).addColumnName("BAR");
+
+		assertEquals("BAR", table.uniqueConstraintAt(0).columnNames().next());
+		assertEquals("FOO", table.uniqueConstraintAt(1).columnNames().next());
+		assertEquals(0, table.uniqueConstraintAt(2).columnNamesSize());
+
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(name = \"MY_JOIN_TABLE\", uniqueConstraints = {@UniqueConstraint(columnNames = \"BAR\"),@UniqueConstraint(columnNames = \"FOO\"), @UniqueConstraint}))", cu);
+	}
+	
+	public void testJoinTableRemoveUniqueConstraint() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithUniqueConstraints();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertEquals("BAR", table.uniqueConstraintAt(0).columnNames().next());
+		assertEquals("FOO", table.uniqueConstraintAt(1).columnNames().next());
+		assertEquals("BAZ", table.uniqueConstraintAt(2).columnNames().next());
+		assertEquals(3, table.uniqueConstraintsSize());
+		
+		table.removeUniqueConstraint(1);
+		assertEquals("BAR", table.uniqueConstraintAt(0).columnNames().next());
+		assertEquals("BAZ", table.uniqueConstraintAt(1).columnNames().next());
+		assertEquals(2, table.uniqueConstraintsSize());		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(uniqueConstraints = {@UniqueConstraint(columnNames = {\"BAR\"}), @UniqueConstraint(columnNames = {\"BAZ\"})}))", cu);
+		
+		table.removeUniqueConstraint(0);
+		assertEquals("BAZ", table.uniqueConstraintAt(0).columnNames().next());
+		assertEquals(1, table.uniqueConstraintsSize());		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(uniqueConstraints = @UniqueConstraint(columnNames = {\"BAZ\"})))", cu);
+		
+		table.removeUniqueConstraint(0);
+		assertEquals(0, table.uniqueConstraintsSize());		
+		assertSourceDoesNotContain("@JoinTable", cu);
+	}
+	
+	public void testJoinTableMoveUniqueConstraint() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithUniqueConstraints();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(uniqueConstraints = {@UniqueConstraint(columnNames = {\"BAR\"}), @UniqueConstraint(columnNames = {\"FOO\"}), @UniqueConstraint(columnNames = {\"BAZ\"})}))", cu);
+		
+		table.moveUniqueConstraint(2, 0);
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(uniqueConstraints = {@UniqueConstraint(columnNames = {\"FOO\"}), @UniqueConstraint(columnNames = {\"BAZ\"}), @UniqueConstraint(columnNames = {\"BAR\"})}))", cu);
+	}
+	
+	public void testJoinTableMoveUniqueConstraint2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithUniqueConstraints();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(uniqueConstraints = {@UniqueConstraint(columnNames = {\"BAR\"}), @UniqueConstraint(columnNames = {\"FOO\"}), @UniqueConstraint(columnNames = {\"BAZ\"})}))", cu);
+		
+		table.moveUniqueConstraint(0, 2);
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(uniqueConstraints = {@UniqueConstraint(columnNames = {\"BAZ\"}), @UniqueConstraint(columnNames = {\"BAR\"}), @UniqueConstraint(columnNames = {\"FOO\"})}))", cu);
+	}
+	
+	public void testJoinTableJoinColumns() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+				
+		assertEquals(0, table.joinColumnsSize());
+	}
+	
+	public void testJoinTableJoinColumns2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+
+		
+		table.addJoinColumn(0);
+		table.addJoinColumn(1);
+		
+		assertEquals(2, table.joinColumnsSize());
+	}
+	
+	public void testJoinTableJoinColumns3() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+				
+		assertEquals(2, table.joinColumnsSize());
+	}
+	
+	public void testJoinTableAddJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		
+		table.addJoinColumn(0).setName("FOO");
+		table.addJoinColumn(1);
+		table.addJoinColumn(0).setName("BAR");
+
+		assertEquals("BAR", table.joinColumnAt(0).getName());
+		assertEquals("FOO", table.joinColumnAt(1).getName());
+		assertNull(table.joinColumnAt(2).getName());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(name = \"MY_JOIN_TABLE\", joinColumns = {@JoinColumn(name = \"BAR\"),@JoinColumn(name = \"FOO\"), @JoinColumn}))", cu);
+	}
+	
+	public void testJoinTableRemoveJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		table.addJoinColumn(0).setName("FOO");
+		
+		assertEquals("FOO", table.joinColumnAt(0).getName());
+		assertEquals("BAR", table.joinColumnAt(1).getName());
+		assertNull(table.joinColumnAt(2).getName());
+		assertEquals(3, table.joinColumnsSize());
+		
+		table.removeJoinColumn(1);
+		assertEquals("FOO", table.joinColumnAt(0).getName());
+		assertNull(table.joinColumnAt(1).getName());
+		assertEquals(2, table.joinColumnsSize());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = {@JoinColumn(name = \"FOO\"), @JoinColumn}))", cu);
+
+		table.removeJoinColumn(0);
+		assertNull(table.joinColumnAt(0).getName());
+		assertEquals(1, table.joinColumnsSize());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = @JoinColumn))", cu);
+
+		
+		table.removeJoinColumn(0);
+		assertEquals(0, table.joinColumnsSize());
+		assertSourceDoesNotContain("@JoinTable", cu);
+	}
+	
+	public void testJoinTableMoveJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		JoinColumnAnnotation joinColumn = table.joinColumnAt(0);
+		joinColumn.setReferencedColumnName("REF_NAME");
+		joinColumn.setUnique(Boolean.FALSE);
+		joinColumn.setNullable(Boolean.FALSE);
+		joinColumn.setInsertable(Boolean.FALSE);
+		joinColumn.setUpdatable(Boolean.FALSE);
+		joinColumn.setColumnDefinition("COLUMN_DEF");
+		joinColumn.setTable("TABLE");
+		table.addJoinColumn(0).setName("FOO");
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = {@JoinColumn(name = \"FOO\"), @JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\"), @JoinColumn}))", cu);
+
+		table.moveJoinColumn(2, 0);
+		assertEquals("BAR", table.joinColumnAt(0).getName());
+		assertNull(table.joinColumnAt(1).getName());
+		assertEquals("FOO", table.joinColumnAt(2).getName());
+		assertEquals(3, table.joinColumnsSize());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = {@JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\"), @JoinColumn, @JoinColumn(name = \"FOO\")}))", cu);
+	}
+	
+	public void testJoinTableMoveJoinColumn2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		
+		JoinColumnAnnotation joinColumn = table.joinColumnAt(0);
+		joinColumn.setReferencedColumnName("REF_NAME");
+		joinColumn.setUnique(Boolean.FALSE);
+		joinColumn.setNullable(Boolean.FALSE);
+		joinColumn.setInsertable(Boolean.FALSE);
+		joinColumn.setUpdatable(Boolean.FALSE);
+		joinColumn.setColumnDefinition("COLUMN_DEF");
+		joinColumn.setTable("TABLE");
+		
+		table.addJoinColumn(0).setName("FOO");
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = {@JoinColumn(name = \"FOO\"), @JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\"), @JoinColumn}))", cu);
+
+
+		table.moveJoinColumn(0, 2);
+		assertNull(table.joinColumnAt(0).getName());
+		assertEquals("FOO", table.joinColumnAt(1).getName());
+		assertEquals("BAR", table.joinColumnAt(2).getName());
+		assertEquals(3, table.joinColumnsSize());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = {@JoinColumn, @JoinColumn(name = \"FOO\"), @JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\")}))", cu);
+	}
+	
+	public void testJoinTableSetJoinColumnName() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+				
+		assertEquals(2, table.joinColumnsSize());
+		
+		JoinColumnAnnotation joinColumn = table.joinColumns().next();
+		
+		assertEquals("BAR", joinColumn.getName());
+		
+		joinColumn.setName("foo");
+		assertEquals("foo", joinColumn.getName());
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = {@JoinColumn(name = \"foo\"), @JoinColumn}))", cu);
+	}
+
+	public void testJoinTableInverseJoinColumns() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		
+		assertEquals(0, table.inverseJoinColumnsSize());
+	}
+	
+	public void testInverseJoinColumns2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+
+		
+		table.addInverseJoinColumn(0);
+		table.addInverseJoinColumn(1);
+		
+		assertEquals(2, table.inverseJoinColumnsSize());
+	}
+	
+	public void testJoinTableInverseJoinColumns3() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithInverseJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+				
+		assertEquals(2, table.inverseJoinColumnsSize());
+	}
+	
+	public void testAddInverseJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		
+		table.addInverseJoinColumn(0).setName("FOO");
+		table.addInverseJoinColumn(1);
+		table.addInverseJoinColumn(0).setName("BAR");
+
+		assertEquals("BAR", table.inverseJoinColumnAt(0).getName());
+		assertEquals("FOO", table.inverseJoinColumnAt(1).getName());
+		assertNull(table.inverseJoinColumnAt(2).getName());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(name = \"MY_JOIN_TABLE\", inverseJoinColumns = {@JoinColumn(name = \"BAR\"),@JoinColumn(name = \"FOO\"), @JoinColumn}))", cu);
+	}
+	
+	public void testJoinTableRemoveInverseJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithInverseJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		table.addInverseJoinColumn(2).setName("FOO");
+		
+		Iterator<JoinColumnAnnotation> inverseJoinColumns = table.inverseJoinColumns();
+		assertEquals("BAR", inverseJoinColumns.next().getName());
+		assertNull(inverseJoinColumns.next().getName());
+		assertEquals("FOO", inverseJoinColumns.next().getName());
+		assertFalse(inverseJoinColumns.hasNext());
+		
+		table.removeInverseJoinColumn(1);
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(inverseJoinColumns = {@JoinColumn(name = \"BAR\"), @JoinColumn(name = \"FOO\")}))", cu);
+		inverseJoinColumns = table.inverseJoinColumns();
+		assertEquals("BAR", inverseJoinColumns.next().getName());
+		assertEquals("FOO", inverseJoinColumns.next().getName());
+		assertFalse(inverseJoinColumns.hasNext());
+
+		table.removeInverseJoinColumn(0);
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(inverseJoinColumns = @JoinColumn(name = \"FOO\")))", cu);
+		inverseJoinColumns = table.inverseJoinColumns();
+		assertEquals("FOO", inverseJoinColumns.next().getName());
+		assertFalse(inverseJoinColumns.hasNext());
+		
+		table.removeInverseJoinColumn(0);
+		assertSourceDoesNotContain("@JoinTable", cu);
+	}
+	
+	public void testJoinTableMoveInverseJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithInverseJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		table.addInverseJoinColumn(0).setName("FOO");
+		
+		Iterator<JoinColumnAnnotation> inverseJoinColumns = table.inverseJoinColumns();
+		assertEquals("FOO", inverseJoinColumns.next().getName());
+		assertEquals("BAR", inverseJoinColumns.next().getName());
+		assertNull(inverseJoinColumns.next().getName());
+		
+		table.moveInverseJoinColumn(2, 0);
+		inverseJoinColumns = table.inverseJoinColumns();
+		assertEquals("BAR", inverseJoinColumns.next().getName());
+		assertNull(inverseJoinColumns.next().getName());
+		assertEquals("FOO", inverseJoinColumns.next().getName());
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(inverseJoinColumns = {@JoinColumn(name = \"BAR\"), @JoinColumn, @JoinColumn(name = \"FOO\")}))", cu);
+	}
+	
+	public void testJoinTableMoveInverseJoinColumn2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithInverseJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		table.addInverseJoinColumn(1).setName("FOO");
+		
+		Iterator<JoinColumnAnnotation> inverseJoinColumns = table.inverseJoinColumns();
+		assertEquals("BAR", inverseJoinColumns.next().getName());
+		assertEquals("FOO", inverseJoinColumns.next().getName());
+		assertNull(inverseJoinColumns.next().getName());
+		
+		table.moveInverseJoinColumn(0, 2);
+		inverseJoinColumns = table.inverseJoinColumns();
+		assertNull(inverseJoinColumns.next().getName());
+		assertEquals("BAR", inverseJoinColumns.next().getName());
+		assertEquals("FOO", inverseJoinColumns.next().getName());
+
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(inverseJoinColumns = {@JoinColumn, @JoinColumn(name = \"BAR\"), @JoinColumn(name = \"FOO\")}))", cu);
+	}
+	
+	public void testJoinTableSetInverseJoinColumnName() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithInverseJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE);
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+				
+		assertEquals(2, table.inverseJoinColumnsSize());
+		
+		JoinColumnAnnotation joinColumn = table.inverseJoinColumns().next();
+		
+		assertEquals("BAR", joinColumn.getName());
+		
+		joinColumn.setName("foo");
+		assertEquals("foo", joinColumn.getName());
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(inverseJoinColumns = {@JoinColumn(name = \"foo\"), @JoinColumn}))", cu);
+	}
+
+}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt2_0/core/tests/internal/resource/java/AssociationOverrides2_0Tests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt2_0/core/tests/internal/resource/java/AssociationOverrides2_0Tests.java
new file mode 100644
index 0000000..0b4e8fe
--- /dev/null
+++ b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt2_0/core/tests/internal/resource/java/AssociationOverrides2_0Tests.java
@@ -0,0 +1,988 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.jpt2_0.core.tests.internal.resource.java;
+
+import java.util.Iterator;
+
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jpt.core.resource.java.AssociationOverrideAnnotation;
+import org.eclipse.jpt.core.resource.java.AssociationOverridesAnnotation;
+import org.eclipse.jpt.core.resource.java.JPA;
+import org.eclipse.jpt.core.resource.java.JavaResourcePersistentAttribute;
+import org.eclipse.jpt.core.resource.java.JavaResourcePersistentType;
+import org.eclipse.jpt.core.resource.java.JoinColumnAnnotation;
+import org.eclipse.jpt.core.resource.java.JoinTableAnnotation;
+import org.eclipse.jpt.core.resource.java.NestableAnnotation;
+import org.eclipse.jpt.utility.internal.CollectionTools;
+import org.eclipse.jpt.utility.internal.iterators.ArrayIterator;
+import org.eclipse.jpt2_0.core.resource.java.AssociationOverride2_0Annotation;
+
+@SuppressWarnings("nls")
+public class AssociationOverrides2_0Tests extends Generic2_0JavaResourceModelTestCase {
+	
+	private static final String ASSOCIATION_OVERRIDE_NAME = "MY_ASSOCIATION_OVERRIDE";
+	private static final String JOIN_TABLE_NAME = "MY_JOIN_TABLE";
+	private static final String CATALOG_NAME = "MY_CATALOG";
+	private static final String SCHEMA_NAME = "MY_SCHEMA";
+	
+	public AssociationOverrides2_0Tests(String name) {
+		super(name);
+	}
+
+	private ICompilationUnit createTestAssociationOverrideOnField() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES);
+			}
+			@Override
+			public void appendIdFieldAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\"))");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideWithJoinColumns() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES, JPA.JOIN_COLUMN);
+			}
+			@Override
+			public void appendIdFieldAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"BAR\"), @JoinColumn}))");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverride() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ENTITY, JPA.ASSOCIATION_OVERRIDE, JPA.JOIN_COLUMN);
+			}
+			@Override
+			public void appendTypeAnnotationTo(StringBuilder sb) {
+				sb.append("@Entity");
+				sb.append(CR);
+				sb.append("@AssociationOverride(name = \"FOO\", joinColumns = @JoinColumn(name = \"FOO\", columnDefinition = \"BAR\", referencedColumnName = \"BAZ\"))");
+			}
+		});
+	}
+
+	private ICompilationUnit createTestAssociationOverrideOnType() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDES, JPA.ASSOCIATION_OVERRIDE);
+			}
+			@Override
+			public void appendTypeAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\"))");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideWithJoinTable() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDES, JPA.ASSOCIATION_OVERRIDE, JPA.JOIN_TABLE);
+			}
+			@Override
+			public void appendTypeAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(name = \"" + JOIN_TABLE_NAME + "\")))");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideJoinTableWithCatalog() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDES, JPA.ASSOCIATION_OVERRIDE, JPA.JOIN_TABLE);
+			}
+			@Override
+			public void appendTypeAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(catalog = \"" + CATALOG_NAME + "\")))");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideJoinTableWithSchema() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDES, JPA.ASSOCIATION_OVERRIDE, JPA.JOIN_TABLE);
+			}
+			@Override
+			public void appendTypeAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(schema = \"" + SCHEMA_NAME + "\")))");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideJoinTableWithUniqueConstraints() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDES, JPA.ASSOCIATION_OVERRIDE, JPA.JOIN_TABLE, JPA.UNIQUE_CONSTRAINT);
+			}
+			@Override
+			public void appendTypeAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(uniqueConstraints = {@UniqueConstraint(columnNames = {\"BAR\"}), @UniqueConstraint(columnNames = {\"FOO\"}), @UniqueConstraint(columnNames = {\"BAZ\"})})))");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideJoinTableWithJoinColumns() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDES, JPA.ASSOCIATION_OVERRIDE, JPA.JOIN_TABLE, JPA.JOIN_COLUMN);
+			}
+			@Override
+			public void appendTypeAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = {@JoinColumn(name = \"BAR\"), @JoinColumn})))");
+			}
+		});
+	}
+	
+	private ICompilationUnit createTestAssociationOverrideJoinTableWithInverseJoinColumns() throws Exception {
+		return this.createTestType(new DefaultAnnotationWriter() {
+			@Override
+			public Iterator<String> imports() {
+				return new ArrayIterator<String>(JPA.ASSOCIATION_OVERRIDES, JPA.ASSOCIATION_OVERRIDE, JPA.JOIN_TABLE, JPA.JOIN_COLUMN);
+			}
+			@Override
+			public void appendTypeAnnotationTo(StringBuilder sb) {
+				sb.append("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(inverseJoinColumns = {@JoinColumn(name = \"BAR\"), @JoinColumn})))");
+			}
+		});
+	}
+	
+	
+	public void testGetName() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnField();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) attributeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverrideAnnotation associationOverride = associationOverrides.nestedAnnotations().next();
+
+		assertNotNull(associationOverride);
+		assertEquals(ASSOCIATION_OVERRIDE_NAME, associationOverride.getName());
+	}
+
+	public void testSetName() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnField();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) attributeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverrideAnnotation associationOverride = associationOverrides.nestedAnnotations().next();
+
+		assertNotNull(associationOverride);
+		assertEquals(ASSOCIATION_OVERRIDE_NAME, associationOverride.getName());
+
+		associationOverride.setName("Foo");
+		assertEquals("Foo", associationOverride.getName());
+		assertSourceContains("@AssociationOverrides(@AssociationOverride(name = \"Foo\"))", cu);
+	}
+	
+	public void testSetNameNull() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnField();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) attributeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverrideAnnotation associationOverride = associationOverrides.nestedAnnotations().next();
+		assertEquals(ASSOCIATION_OVERRIDE_NAME, associationOverride.getName());
+		
+		associationOverride.setName(null);
+		assertNull(associationOverride.getName());
+		
+		assertSourceDoesNotContain("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\")", cu);
+		assertSourceContains("@AssociationOverride", cu);
+		assertSourceContains("@AssociationOverrides", cu);
+	}
+	
+	public void testAddAssociationOverrideCopyExisting() throws Exception {
+		ICompilationUnit cu = createTestAssociationOverride();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) typeResource.addSupportingAnnotation(1, JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES);
+		associationOverride.setName("BAR");
+		assertSourceContains("@AssociationOverrides({@AssociationOverride(name = \"FOO\", joinColumns = @JoinColumn(name = \"FOO\", columnDefinition = \"BAR\", referencedColumnName = \"BAZ\")),@AssociationOverride(name = \"BAR\")})", cu);
+		
+		assertNull(typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE));
+		assertNotNull(typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES));
+		assertEquals(2, CollectionTools.size(typeResource.supportingAnnotations(JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES)));
+	}
+	
+	public void testAddAssociationOverrideToBeginningOfList() throws Exception {
+		ICompilationUnit cu = createTestAssociationOverride();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) typeResource.addSupportingAnnotation(1, JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES);
+		associationOverride.setName("BAR");
+		assertSourceContains("@AssociationOverrides({@AssociationOverride(name = \"FOO\", joinColumns = @JoinColumn(name = \"FOO\", columnDefinition = \"BAR\", referencedColumnName = \"BAZ\")),@AssociationOverride(name = \"BAR\")})", cu);
+		
+		associationOverride = (AssociationOverrideAnnotation) typeResource.addSupportingAnnotation(0, JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES);
+		associationOverride.setName("BAZ");
+		assertSourceContains("@AssociationOverrides({@AssociationOverride(name = \"BAZ\"),@AssociationOverride(name = \"FOO\", joinColumns = @JoinColumn(name = \"FOO\", columnDefinition = \"BAR\", referencedColumnName = \"BAZ\")), @AssociationOverride(name = \"BAR\")})", cu);
+
+		Iterator<NestableAnnotation> associationOverrides = typeResource.supportingAnnotations(JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES);
+		assertEquals("BAZ", ((AssociationOverrideAnnotation) associationOverrides.next()).getName());
+		assertEquals("FOO", ((AssociationOverrideAnnotation) associationOverrides.next()).getName());
+		assertEquals("BAR", ((AssociationOverrideAnnotation) associationOverrides.next()).getName());
+
+		assertNull(typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDE));
+		assertNotNull(typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES));
+		assertEquals(3, CollectionTools.size(typeResource.supportingAnnotations(JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES)));
+	}
+
+	public void testRemoveAssociationOverrideCopyExisting() throws Exception {
+		ICompilationUnit cu = createTestAssociationOverride();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) typeResource.addSupportingAnnotation(1, JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES);
+		associationOverride.setName("BAR");
+		assertSourceContains("@AssociationOverrides({@AssociationOverride(name = \"FOO\", joinColumns = @JoinColumn(name = \"FOO\", columnDefinition = \"BAR\", referencedColumnName = \"BAZ\")),@AssociationOverride(name = \"BAR\")})", cu);
+		
+		typeResource.removeSupportingAnnotation(1, JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES);
+		assertSourceContains("@AssociationOverride(name = \"FOO\", joinColumns = @JoinColumn(name = \"FOO\", columnDefinition = \"BAR\", referencedColumnName = \"BAZ\"))", cu);
+	}
+	
+	public void testJoinColumns() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnField();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.supportingAnnotations(JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES).next();
+		
+		assertEquals(0, associationOverride.joinColumnsSize());
+	}
+	
+	public void testJoinColumns2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnField();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.supportingAnnotations(JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES).next();
+		
+		associationOverride.addJoinColumn(0);
+		associationOverride.addJoinColumn(1);
+		
+		assertEquals(2, associationOverride.joinColumnsSize());
+	}
+	
+	public void testJoinColumns3() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.supportingAnnotations(JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES).next();
+				
+		assertEquals(2, associationOverride.joinColumnsSize());
+	}
+	
+	public void testAddJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnField();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.supportingAnnotations(JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES).next();
+		
+		associationOverride.addJoinColumn(0).setName("FOO");
+		associationOverride.addJoinColumn(1);
+		associationOverride.addJoinColumn(0).setName("BAR");
+
+
+		Iterator<JoinColumnAnnotation> joinColumns = associationOverride.joinColumns();
+		assertEquals("BAR", joinColumns.next().getName());
+		assertEquals("FOO", joinColumns.next().getName());
+		assertNull(joinColumns.next().getName());
+	
+		assertSourceContains("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"BAR\"),@JoinColumn(name = \"FOO\"), @JoinColumn}))", cu);
+	}
+	
+	public void testRemoveJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.supportingAnnotations(JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES).next();
+		associationOverride.addJoinColumn(0).setName("FOO");
+		
+		Iterator<JoinColumnAnnotation> joinColumns = associationOverride.joinColumns();
+		assertEquals("FOO", joinColumns.next().getName());
+		assertEquals("BAR", joinColumns.next().getName());
+		assertNull(joinColumns.next().getName());
+		assertEquals(false, joinColumns.hasNext());
+		assertSourceContains("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"FOO\"), @JoinColumn(name = \"BAR\"), @JoinColumn}))", cu);
+		
+		associationOverride.removeJoinColumn(1);
+		joinColumns = associationOverride.joinColumns();
+		assertEquals("FOO", joinColumns.next().getName());
+		assertNull(joinColumns.next().getName());
+		assertEquals(false, joinColumns.hasNext());
+		assertSourceContains("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"FOO\"), @JoinColumn}))", cu);
+
+		associationOverride.removeJoinColumn(0);
+		joinColumns = associationOverride.joinColumns();
+		assertNull(joinColumns.next().getName());
+		assertEquals(false, joinColumns.hasNext());
+		assertSourceContains("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = @JoinColumn))", cu);
+
+		
+		associationOverride.setName(null);
+		associationOverride.removeJoinColumn(0);
+		assertSourceDoesNotContain("@AssociationOverride", cu);
+	}
+	
+	public void testMoveJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.supportingAnnotations(JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES).next();
+		JoinColumnAnnotation joinColumn = associationOverride.joinColumnAt(0);
+		joinColumn.setReferencedColumnName("REF_NAME");
+		joinColumn.setUnique(Boolean.FALSE);
+		joinColumn.setNullable(Boolean.FALSE);
+		joinColumn.setInsertable(Boolean.FALSE);
+		joinColumn.setUpdatable(Boolean.FALSE);
+		joinColumn.setColumnDefinition("COLUMN_DEF");
+		joinColumn.setTable("TABLE");
+		associationOverride.addJoinColumn(0).setName("FOO");
+		assertSourceContains("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"FOO\"), @JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\"), @JoinColumn}))", cu);
+
+		associationOverride.moveJoinColumn(2, 0);
+		assertEquals("BAR", associationOverride.joinColumnAt(0).getName());
+		assertNull(associationOverride.joinColumnAt(1).getName());
+		assertEquals("FOO", associationOverride.joinColumnAt(2).getName());
+		assertEquals(3, associationOverride.joinColumnsSize());
+		assertSourceContains("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\"), @JoinColumn, @JoinColumn(name = \"FOO\")}))", cu);
+	}
+	
+	public void testMoveJoinColumn2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.supportingAnnotations(JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES).next();
+		
+		JoinColumnAnnotation joinColumn = associationOverride.joinColumnAt(0);
+		joinColumn.setReferencedColumnName("REF_NAME");
+		joinColumn.setUnique(Boolean.FALSE);
+		joinColumn.setNullable(Boolean.FALSE);
+		joinColumn.setInsertable(Boolean.FALSE);
+		joinColumn.setUpdatable(Boolean.FALSE);
+		joinColumn.setColumnDefinition("COLUMN_DEF");
+		joinColumn.setTable("TABLE");
+		associationOverride.addJoinColumn(0).setName("FOO");
+		
+		assertSourceContains("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"FOO\"), @JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\"), @JoinColumn}))", cu);
+		associationOverride.moveJoinColumn(0, 2);
+		assertNull(associationOverride.joinColumnAt(0).getName());
+		assertEquals("FOO", associationOverride.joinColumnAt(1).getName());
+		assertEquals("BAR", associationOverride.joinColumnAt(2).getName());
+		assertEquals(3, associationOverride.joinColumnsSize());
+		assertSourceContains("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn, @JoinColumn(name = \"FOO\"), @JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\")}))", cu);
+	}
+	
+	public void testSetJoinColumnName() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		JavaResourcePersistentAttribute attributeResource = typeResource.fields().next();
+		
+		AssociationOverrideAnnotation associationOverride = (AssociationOverrideAnnotation) attributeResource.supportingAnnotations(JPA.ASSOCIATION_OVERRIDE, JPA.ASSOCIATION_OVERRIDES).next();
+				
+		assertEquals(2, associationOverride.joinColumnsSize());
+		
+		JoinColumnAnnotation joinColumn = associationOverride.joinColumns().next();
+		
+		assertEquals("BAR", joinColumn.getName());
+		
+		joinColumn.setName("foo");
+		assertEquals("foo", joinColumn.getName());
+		
+		assertSourceContains("@AssociationOverrides(@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinColumns = {@JoinColumn(name = \"foo\"), @JoinColumn}))", cu);
+	}	
+	
+	public void testGetNullJoinTable() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnType();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation joinTable = associationOverride.getJoinTable();
+		assertNotNull(associationOverride);
+		assertNull(joinTable);
+	}
+	
+	public void testJoinTableGetName() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation joinTable = associationOverride.getJoinTable();
+		assertEquals(JOIN_TABLE_NAME, joinTable.getName());
+	}
+	
+	public void testJoinTableSetName() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation joinTable = associationOverride.getJoinTable();
+		assertEquals(JOIN_TABLE_NAME, joinTable.getName());
+		
+		joinTable.setName("Foo");
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(name = \"Foo\"))", cu);
+		
+		joinTable.setName(null);
+		assertNull(associationOverride.getJoinTable());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\")", cu);
+	}
+	
+	public void testAddJoinTable() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnType();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation joinTable = associationOverride.getJoinTable();
+		assertNull(joinTable);
+		
+		associationOverride.addJoinTable();
+		joinTable = associationOverride.getJoinTable();
+		assertNotNull(joinTable);
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable)", cu);
+	}
+	
+	public void testRemoveJoinTable() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideOnType();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation joinTable = associationOverride.getJoinTable();
+		assertNull(joinTable);
+	}
+	
+	public void testJoinTableGetCatalog() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithCatalog();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertNotNull(table);
+		assertEquals(CATALOG_NAME, table.getCatalog());
+	}
+
+	public void testJoinTableSetCatalog() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertNotNull(table);
+		assertNull(table.getCatalog());
+
+		table.setCatalog("Foo");
+		assertEquals("Foo", table.getCatalog());
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(name = \"MY_JOIN_TABLE\", catalog = \"Foo\"))", cu);
+	}
+	
+	public void testJoinTableSetCatalogNull() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithCatalog();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertEquals(CATALOG_NAME, table.getCatalog());
+		
+		table.setCatalog(null);
+		assertNull(table.getCatalog());
+		
+		assertSourceDoesNotContain("@JoinTable", cu);
+	}
+	
+	public void testJoinTableGetSchema() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithSchema();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertNotNull(table);
+		assertEquals(SCHEMA_NAME, table.getSchema());
+	}
+
+	public void testJoinTableSetSchema() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertNotNull(table);
+		assertNull(table.getSchema());
+
+		table.setSchema("Foo");
+		assertEquals("Foo", table.getSchema());
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(name = \"MY_JOIN_TABLE\", schema = \"Foo\"))", cu);
+	}
+	
+	public void testJoinTableSetSchemaNull() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithSchema();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertEquals(SCHEMA_NAME, table.getSchema());
+		
+		table.setSchema(null);
+		assertNull(table.getSchema());
+		
+		assertSourceDoesNotContain("@JoinTable", cu);
+	}
+	
+	public void testJoinTableUniqueConstraints() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		
+		assertEquals(0, table.uniqueConstraintsSize());
+	}
+	
+	public void testJoinTableUniqueConstraints2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+
+		
+		table.addUniqueConstraint(0);
+		table.addUniqueConstraint(1);
+		
+		assertEquals(2, table.uniqueConstraintsSize());
+	}
+	
+	public void testJoinTableUniqueConstraints3() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithUniqueConstraints();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+				
+		assertEquals(3, table.uniqueConstraintsSize());
+	}
+	
+	public void testJoinTableAddUniqueConstraint() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		
+		table.addUniqueConstraint(0).addColumnName("FOO");
+		table.addUniqueConstraint(1);
+		table.addUniqueConstraint(0).addColumnName("BAR");
+
+		assertEquals("BAR", table.uniqueConstraintAt(0).columnNames().next());
+		assertEquals("FOO", table.uniqueConstraintAt(1).columnNames().next());
+		assertEquals(0, table.uniqueConstraintAt(2).columnNamesSize());
+
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(name = \"MY_JOIN_TABLE\", uniqueConstraints = {@UniqueConstraint(columnNames = \"BAR\"),@UniqueConstraint(columnNames = \"FOO\"), @UniqueConstraint}))", cu);
+	}
+	
+	public void testJoinTableRemoveUniqueConstraint() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithUniqueConstraints();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertEquals("BAR", table.uniqueConstraintAt(0).columnNames().next());
+		assertEquals("FOO", table.uniqueConstraintAt(1).columnNames().next());
+		assertEquals("BAZ", table.uniqueConstraintAt(2).columnNames().next());
+		assertEquals(3, table.uniqueConstraintsSize());
+		
+		table.removeUniqueConstraint(1);
+		assertEquals("BAR", table.uniqueConstraintAt(0).columnNames().next());
+		assertEquals("BAZ", table.uniqueConstraintAt(1).columnNames().next());
+		assertEquals(2, table.uniqueConstraintsSize());		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(uniqueConstraints = {@UniqueConstraint(columnNames = {\"BAR\"}), @UniqueConstraint(columnNames = {\"BAZ\"})}))", cu);
+		
+		table.removeUniqueConstraint(0);
+		assertEquals("BAZ", table.uniqueConstraintAt(0).columnNames().next());
+		assertEquals(1, table.uniqueConstraintsSize());		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(uniqueConstraints = @UniqueConstraint(columnNames = {\"BAZ\"})))", cu);
+		
+		table.removeUniqueConstraint(0);
+		assertEquals(0, table.uniqueConstraintsSize());		
+		assertSourceDoesNotContain("@JoinTable", cu);
+	}
+	
+	public void testJoinTableMoveUniqueConstraint() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithUniqueConstraints();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(uniqueConstraints = {@UniqueConstraint(columnNames = {\"BAR\"}), @UniqueConstraint(columnNames = {\"FOO\"}), @UniqueConstraint(columnNames = {\"BAZ\"})}))", cu);
+		
+		table.moveUniqueConstraint(2, 0);
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(uniqueConstraints = {@UniqueConstraint(columnNames = {\"FOO\"}), @UniqueConstraint(columnNames = {\"BAZ\"}), @UniqueConstraint(columnNames = {\"BAR\"})}))", cu);
+	}
+	
+	public void testJoinTableMoveUniqueConstraint2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithUniqueConstraints();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(uniqueConstraints = {@UniqueConstraint(columnNames = {\"BAR\"}), @UniqueConstraint(columnNames = {\"FOO\"}), @UniqueConstraint(columnNames = {\"BAZ\"})}))", cu);
+		
+		table.moveUniqueConstraint(0, 2);
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(uniqueConstraints = {@UniqueConstraint(columnNames = {\"BAZ\"}), @UniqueConstraint(columnNames = {\"BAR\"}), @UniqueConstraint(columnNames = {\"FOO\"})}))", cu);
+	}
+	
+	public void testJoinTableJoinColumns() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+				
+		assertEquals(0, table.joinColumnsSize());
+	}
+	
+	public void testJoinTableJoinColumns2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+
+		
+		table.addJoinColumn(0);
+		table.addJoinColumn(1);
+		
+		assertEquals(2, table.joinColumnsSize());
+	}
+	
+	public void testJoinTableJoinColumns3() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+				
+		assertEquals(2, table.joinColumnsSize());
+	}
+	
+	public void testJoinTableAddJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		
+		table.addJoinColumn(0).setName("FOO");
+		table.addJoinColumn(1);
+		table.addJoinColumn(0).setName("BAR");
+
+		assertEquals("BAR", table.joinColumnAt(0).getName());
+		assertEquals("FOO", table.joinColumnAt(1).getName());
+		assertNull(table.joinColumnAt(2).getName());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(name = \"MY_JOIN_TABLE\", joinColumns = {@JoinColumn(name = \"BAR\"),@JoinColumn(name = \"FOO\"), @JoinColumn}))", cu);
+	}
+	
+	public void testJoinTableRemoveJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu); 
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		table.addJoinColumn(0).setName("FOO");
+		
+		assertEquals("FOO", table.joinColumnAt(0).getName());
+		assertEquals("BAR", table.joinColumnAt(1).getName());
+		assertNull(table.joinColumnAt(2).getName());
+		assertEquals(3, table.joinColumnsSize());
+		
+		table.removeJoinColumn(1);
+		assertEquals("FOO", table.joinColumnAt(0).getName());
+		assertNull(table.joinColumnAt(1).getName());
+		assertEquals(2, table.joinColumnsSize());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = {@JoinColumn(name = \"FOO\"), @JoinColumn}))", cu);
+
+		table.removeJoinColumn(0);
+		assertNull(table.joinColumnAt(0).getName());
+		assertEquals(1, table.joinColumnsSize());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = @JoinColumn))", cu);
+
+		
+		table.removeJoinColumn(0);
+		assertEquals(0, table.joinColumnsSize());
+		assertSourceDoesNotContain("@JoinTable", cu);
+	}
+	
+	public void testJoinTableMoveJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		JoinColumnAnnotation joinColumn = table.joinColumnAt(0);
+		joinColumn.setReferencedColumnName("REF_NAME");
+		joinColumn.setUnique(Boolean.FALSE);
+		joinColumn.setNullable(Boolean.FALSE);
+		joinColumn.setInsertable(Boolean.FALSE);
+		joinColumn.setUpdatable(Boolean.FALSE);
+		joinColumn.setColumnDefinition("COLUMN_DEF");
+		joinColumn.setTable("TABLE");
+		table.addJoinColumn(0).setName("FOO");
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = {@JoinColumn(name = \"FOO\"), @JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\"), @JoinColumn}))", cu);
+
+		table.moveJoinColumn(2, 0);
+		assertEquals("BAR", table.joinColumnAt(0).getName());
+		assertNull(table.joinColumnAt(1).getName());
+		assertEquals("FOO", table.joinColumnAt(2).getName());
+		assertEquals(3, table.joinColumnsSize());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = {@JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\"), @JoinColumn, @JoinColumn(name = \"FOO\")}))", cu);
+	}
+	
+	public void testJoinTableMoveJoinColumn2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		
+		JoinColumnAnnotation joinColumn = table.joinColumnAt(0);
+		joinColumn.setReferencedColumnName("REF_NAME");
+		joinColumn.setUnique(Boolean.FALSE);
+		joinColumn.setNullable(Boolean.FALSE);
+		joinColumn.setInsertable(Boolean.FALSE);
+		joinColumn.setUpdatable(Boolean.FALSE);
+		joinColumn.setColumnDefinition("COLUMN_DEF");
+		joinColumn.setTable("TABLE");
+		
+		table.addJoinColumn(0).setName("FOO");
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = {@JoinColumn(name = \"FOO\"), @JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\"), @JoinColumn}))", cu);
+
+
+		table.moveJoinColumn(0, 2);
+		assertNull(table.joinColumnAt(0).getName());
+		assertEquals("FOO", table.joinColumnAt(1).getName());
+		assertEquals("BAR", table.joinColumnAt(2).getName());
+		assertEquals(3, table.joinColumnsSize());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = {@JoinColumn, @JoinColumn(name = \"FOO\"), @JoinColumn(name = \"BAR\", referencedColumnName = \"REF_NAME\", unique = false, nullable = false, insertable = false, updatable = false, columnDefinition = \"COLUMN_DEF\", table = \"TABLE\")}))", cu);
+	}
+	
+	public void testJoinTableSetJoinColumnName() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+				
+		assertEquals(2, table.joinColumnsSize());
+		
+		JoinColumnAnnotation joinColumn = table.joinColumns().next();
+		
+		assertEquals("BAR", joinColumn.getName());
+		
+		joinColumn.setName("foo");
+		assertEquals("foo", joinColumn.getName());
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(joinColumns = {@JoinColumn(name = \"foo\"), @JoinColumn}))", cu);
+	}
+
+	public void testJoinTableInverseJoinColumns() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		
+		assertEquals(0, table.inverseJoinColumnsSize());
+	}
+	
+	public void testInverseJoinColumns2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+
+		
+		table.addInverseJoinColumn(0);
+		table.addInverseJoinColumn(1);
+		
+		assertEquals(2, table.inverseJoinColumnsSize());
+	}
+	
+	public void testJoinTableInverseJoinColumns3() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithInverseJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+				
+		assertEquals(2, table.inverseJoinColumnsSize());
+	}
+	
+	public void testAddInverseJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideWithJoinTable();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		
+		table.addInverseJoinColumn(0).setName("FOO");
+		table.addInverseJoinColumn(1);
+		table.addInverseJoinColumn(0).setName("BAR");
+
+		assertEquals("BAR", table.inverseJoinColumnAt(0).getName());
+		assertEquals("FOO", table.inverseJoinColumnAt(1).getName());
+		assertNull(table.inverseJoinColumnAt(2).getName());
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(name = \"MY_JOIN_TABLE\", inverseJoinColumns = {@JoinColumn(name = \"BAR\"),@JoinColumn(name = \"FOO\"), @JoinColumn}))", cu);
+	}
+	
+	public void testJoinTableRemoveInverseJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithInverseJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		table.addInverseJoinColumn(2).setName("FOO");
+		
+		Iterator<JoinColumnAnnotation> inverseJoinColumns = table.inverseJoinColumns();
+		assertEquals("BAR", inverseJoinColumns.next().getName());
+		assertNull(inverseJoinColumns.next().getName());
+		assertEquals("FOO", inverseJoinColumns.next().getName());
+		assertFalse(inverseJoinColumns.hasNext());
+		
+		table.removeInverseJoinColumn(1);
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(inverseJoinColumns = {@JoinColumn(name = \"BAR\"), @JoinColumn(name = \"FOO\")}))", cu);
+		inverseJoinColumns = table.inverseJoinColumns();
+		assertEquals("BAR", inverseJoinColumns.next().getName());
+		assertEquals("FOO", inverseJoinColumns.next().getName());
+		assertFalse(inverseJoinColumns.hasNext());
+
+		table.removeInverseJoinColumn(0);
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(inverseJoinColumns = @JoinColumn(name = \"FOO\")))", cu);
+		inverseJoinColumns = table.inverseJoinColumns();
+		assertEquals("FOO", inverseJoinColumns.next().getName());
+		assertFalse(inverseJoinColumns.hasNext());
+		
+		table.removeInverseJoinColumn(0);
+		assertSourceDoesNotContain("@JoinTable", cu);
+	}
+	
+	public void testJoinTableMoveInverseJoinColumn() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithInverseJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		table.addInverseJoinColumn(0).setName("FOO");
+		
+		Iterator<JoinColumnAnnotation> inverseJoinColumns = table.inverseJoinColumns();
+		assertEquals("FOO", inverseJoinColumns.next().getName());
+		assertEquals("BAR", inverseJoinColumns.next().getName());
+		assertNull(inverseJoinColumns.next().getName());
+		
+		table.moveInverseJoinColumn(2, 0);
+		inverseJoinColumns = table.inverseJoinColumns();
+		assertEquals("BAR", inverseJoinColumns.next().getName());
+		assertNull(inverseJoinColumns.next().getName());
+		assertEquals("FOO", inverseJoinColumns.next().getName());
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(inverseJoinColumns = {@JoinColumn(name = \"BAR\"), @JoinColumn, @JoinColumn(name = \"FOO\")}))", cu);
+	}
+	
+	public void testJoinTableMoveInverseJoinColumn2() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithInverseJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+		table.addInverseJoinColumn(1).setName("FOO");
+		
+		Iterator<JoinColumnAnnotation> inverseJoinColumns = table.inverseJoinColumns();
+		assertEquals("BAR", inverseJoinColumns.next().getName());
+		assertEquals("FOO", inverseJoinColumns.next().getName());
+		assertNull(inverseJoinColumns.next().getName());
+		
+		table.moveInverseJoinColumn(0, 2);
+		inverseJoinColumns = table.inverseJoinColumns();
+		assertNull(inverseJoinColumns.next().getName());
+		assertEquals("BAR", inverseJoinColumns.next().getName());
+		assertEquals("FOO", inverseJoinColumns.next().getName());
+
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(inverseJoinColumns = {@JoinColumn, @JoinColumn(name = \"BAR\"), @JoinColumn(name = \"FOO\")}))", cu);
+	}
+	
+	public void testJoinTableSetInverseJoinColumnName() throws Exception {
+		ICompilationUnit cu = this.createTestAssociationOverrideJoinTableWithInverseJoinColumns();
+		JavaResourcePersistentType typeResource = buildJavaTypeResource(cu);
+		
+		AssociationOverridesAnnotation associationOverrides = (AssociationOverridesAnnotation) typeResource.getSupportingAnnotation(JPA.ASSOCIATION_OVERRIDES);
+		AssociationOverride2_0Annotation associationOverride = (AssociationOverride2_0Annotation) associationOverrides.nestedAnnotations().next();
+		JoinTableAnnotation table = associationOverride.getJoinTable();
+				
+		assertEquals(2, table.inverseJoinColumnsSize());
+		
+		JoinColumnAnnotation joinColumn = table.inverseJoinColumns().next();
+		
+		assertEquals("BAR", joinColumn.getName());
+		
+		joinColumn.setName("foo");
+		assertEquals("foo", joinColumn.getName());
+		
+		assertSourceContains("@AssociationOverride(name = \"" + ASSOCIATION_OVERRIDE_NAME + "\", joinTable = @JoinTable(inverseJoinColumns = {@JoinColumn(name = \"foo\"), @JoinColumn}))", cu);
+	}
+	
+	
+}
diff --git a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt2_0/core/tests/internal/resource/java/Generic2_0JavaResourceTests.java b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt2_0/core/tests/internal/resource/java/Generic2_0JavaResourceTests.java
index bb730f1..bded6c3 100644
--- a/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt2_0/core/tests/internal/resource/java/Generic2_0JavaResourceTests.java
+++ b/jpa/tests/org.eclipse.jpt.core.tests/src/org/eclipse/jpt2_0/core/tests/internal/resource/java/Generic2_0JavaResourceTests.java
@@ -18,6 +18,8 @@
 		TestSuite suite = new TestSuite(Generic2_0JavaResourceTests.class.getName());
 		
 		suite.addTestSuite(AccessAnnotationTests.class);
+		suite.addTestSuite(AssociationOverride2_0Tests.class);
+		suite.addTestSuite(AssociationOverrides2_0Tests.class);
 		suite.addTestSuite(SequenceGenerator2_0Tests.class);
 			
 		return suite;